Merge branch 'develop'

This commit is contained in:
Warunee Tamkoo 2025-09-01 17:09:25 +07:00
commit 05dd1d385f
118 changed files with 5962 additions and 4862 deletions

View file

@ -1,8 +1,18 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import genReport from "@/plugins/genreport";
import { useCounterMixin } from "@/stores/mixin";
import PopupReplyInbox from "@/components/PopupReplyInbox.vue";
import type { Attachments } from "@/modules/01_dashboard/interface/Main";
const $q = useQuasar();
const { showLoader, hideLoader, messageError } = useCounterMixin();
const props = defineProps({
modal: {
type: Boolean,
@ -60,9 +70,29 @@ watch(
const modalReply = ref<boolean>(false);
function fileOpen(url: string) {
window.open(url, "_blank");
}
const fileOpen = async (attachmentsData: Attachments) => {
if (attachmentsData.isReport) {
showLoader();
await http
.get(attachmentsData.url)
.then(async (res) => {
const result = res.data;
if (attachmentsData.isTemplate) {
await genReport(result.result, attachmentsData.name, "pdf");
} else {
window.open(result.downloadUrl, "_blank");
}
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
} else {
window.open(attachmentsData.url, "_blank");
}
};
</script>
<template>
<q-dialog v-model="modal">
@ -116,7 +146,7 @@ function fileOpen(url: string) {
v-for="(item, index) in detail.payload.attachments"
:key="index"
>
<q-item clickable v-close-popup @click.stop="fileOpen(item.url)">
<q-item clickable v-close-popup @click.stop="fileOpen(item)">
<q-item-section>{{ item.name }}</q-item-section>
</q-item>
<q-separator />

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed } from "vue";
import { ref } from "vue";
/** importType*/
import type { QTableProps } from "quasar";
@ -8,29 +8,55 @@ const columns = defineModel<QTableProps["columns"]>("columns", {
required: true,
});
/** จำนวนคอลัมน์ */
const skeletonColumns = computed(() => columns.value?.length || 5);
const rows = ref<Array<{ id: string; name: string }>>([
{
id: "",
name: "",
},
]);
/** ตัวอย่างการใช้งาน */
/// <SkeletonTable v-if="isLoading" :columns="columns" />
</script>
<template>
<q-markup-table flat bordered>
<thead>
<tr>
<th v-for="(n, idx) in skeletonColumns" :key="idx" style="width: 150px">
<q-skeleton type="text" />
</th>
</tr>
</thead>
<d-table
flat
bordered
:columns="columns"
:rows="rows"
row-key="id"
hide-pagination
>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div>
<q-skeleton type="text" width="80px" />
</div>
</q-td>
</q-tr>
</template>
<tbody>
<tr v-for="n in 5" :key="n" :class="n % 2 === 0 ? 'bg-grey-2' : ''">
<td v-for="(col, idx) in skeletonColumns" :key="idx">
<q-skeleton type="text" width="80px" />
</td>
</tr>
</tbody>
</q-markup-table>
<template 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>
<q-list dense class="q-mt-lg relative-position">
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section>
<q-item-label class="text-grey-6 text-weight-medium">{{
col.label
}}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label class="text-dark text-weight-medium">
<q-skeleton type="text" />
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</template>
</d-table>
</template>

View file

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

View file

@ -10,7 +10,6 @@ import type { Permission } from "@/components/Workflow/interface/index/Main";
import type { DataListState } from "@/components/Workflow/interface/response/Main";
import DialogSelectPerson from "@/components/Workflow/DialogSelectPerson.vue";
import Keycloak from "keycloak-js";
const $q = useQuasar();
const { dialogConfirm, showLoader, hideLoader, messageError } =
@ -31,6 +30,7 @@ const stateId = ref<string>(""); //id state ปัจุบัน
const state = ref<number>(1); //state
const isPermission = ref<boolean>(true); // Workflow
const KeycloakId = ref<string>("");
const isLoading = ref<boolean>(false); //
const permission = ref<Permission>({
isChangeState: false, ///
@ -48,6 +48,7 @@ const itemState = ref<DataListState[]>([]);
/** ฟังก์ชันเรียกข้อมูล Workflow ที่อยู่ปัจุบัน*/
async function fetchCheckState() {
isLoading.value = true;
await http
.post(config.API.workflow + `check-user-now`, {
refId: id,
@ -74,6 +75,9 @@ async function fetchCheckState() {
})
.catch(() => {
isPermission.value = false;
})
.finally(() => {
isLoading.value = false;
});
}
@ -129,7 +133,22 @@ defineExpose({
<div class="q-pl-sm text-weight-bold text-dark">สถานะการดำเนนเรอง</div>
</div>
<div class="col-12"><q-separator /></div>
<q-card-section>
<q-card-section class="col-12 q-px-lg q-py-md" v-if="isLoading">
<q-timeline color="primary">
<q-timeline-entry
v-for="(step, index) in 4"
:key="index"
:icon="`mdi-numeric-${index + 1}`"
color="grey-4"
>
<template #title>
<q-skeleton type="rect" width="150px" height="20px" />
</template>
</q-timeline-entry>
</q-timeline>
</q-card-section>
<q-card-section v-else>
<div class="q-px-lg q-py-md">
<q-timeline color="primary">
<q-timeline-entry

View file

@ -0,0 +1,36 @@
/** Namespace สำหรับ Table-related types */
export namespace PropsTable {
/** Interface สำหรับ pagination object */
export interface Pagination {
/** หน้าปัจจุบัน (เริ่มจาก 1) */
page: number;
/** จำนวนแถวต่อหน้า */
rowsPerPage: number;
/** จำนวนแถวทั้งหมด */
rowsNumber?: number;
/** คอลัมน์ที่ใช้ sort */
sortBy?: string;
/** เรียงจากมากไปน้อย */
descending?: boolean;
rowsTotal?: number;
}
/** Interface สำหรับ request props จาก d-table */
export interface RequestProps {
/** ข้อมูล pagination */
pagination: Pagination;
/** ตัวกรองข้อมูล */
filter?: any;
/** function สำหรับดึงค่าจาก cell */
getCellValue?: (col: any, row: any) => any;
}
/** Union type สำหรับ handleRequest function */
export type HandleRequestProps = RequestProps;
}
// Export แบบเดิมเพื่อ backward compatibility
export type TablePagination = PropsTable.Pagination;
export type TableRequestProps = PropsTable.RequestProps;
export type HandleRequestProps = PropsTable.HandleRequestProps;

View file

@ -31,4 +31,11 @@ interface MenuMainList {
active: boolean;
}
export type { InboxList, InboxDetail, MenuMainList };
interface Attachments {
name: string;
url: string;
isReport: boolean;
isTemplate: boolean;
}
export type { InboxList, InboxDetail, MenuMainList, Attachments };

View file

@ -26,8 +26,9 @@ const { showLoader, hideLoader, date2Thai, messageError } = mixin;
const fullname = ref<string>(""); //
const inboxList = ref<InboxDetail[]>([]); //
const idInboxActive = ref<string>(); // Id
//
const isLoadingInbox = ref<boolean>(true); //
//
const filteredItems = computed(() => {
const isOfficer = dataStore.officerType === "OFFICER";
const conditions: Record<string, boolean> = {
@ -148,7 +149,10 @@ const items = ref<MenuMainList[]>([
* @param index หนาทโหลดขอม
*/
const fetchlistInbox = async (index: number) => {
index === 1 && showLoader();
if (index === 1) {
isLoadingInbox.value = true; //
}
index != 0 &&
(await http
.get(config.API.msgInbox + `?page=${index}&pageSize=${10}`)
@ -173,7 +177,7 @@ const fetchlistInbox = async (index: number) => {
}
})
.finally(() => {
hideLoader();
isLoadingInbox.value = false;
}));
};
@ -249,11 +253,17 @@ const totalInbox = ref<number>(0); // จำนวนข้อความทั
*/
async function onLoad(index: number, done: Function) {
const num = index === 1 ? 0 : index++;
if (inboxList.value.length < totalInbox.value) {
setTimeout(() => {
fetchlistInbox(num);
done();
}, 3000);
try {
// infinite scroll
if (inboxList.value.length >= totalInbox.value) {
done(true);
return;
}
await fetchlistInbox(num);
done();
} catch (error) {
done(true);
}
}
@ -284,7 +294,16 @@ onMounted(async () => {
v-for="(item, j) in filteredItems"
:key="j"
>
<q-card bordered @click="goToPage(item.path)" class="noactive col-12">
<q-card v-if="dataStore.isLoadingMenu" bordered class="col-12">
<q-skeleton width="100%" height="180px" />
</q-card>
<q-card
v-else
bordered
@click="goToPage(item.path)"
class="noactive col-12"
>
<div class="col-12">
<q-avatar
:color="item.color"
@ -323,12 +342,28 @@ onMounted(async () => {
กลองขอความ
</div>
<q-space />
<div class="text-grey-5" style="font-size: 12px">
<div v-if="isLoadingInbox">
<q-skeleton type="text" width="80px" />
</div>
<div v-else class="text-grey-5" style="font-size: 12px">
งหมด {{ totalInbox }} อความ
</div>
</div>
<div
v-if="totalInbox != 0"
class="q-pa-sm"
v-if="isLoadingInbox"
style="height: calc(100% - 60px)"
>
<div v-for="(item, index) in 3">
<q-skeleton type="text" width="10%" class="text-subtitle1" />
<q-skeleton type="text" width="50%" class="text-subtitle1" />
<q-skeleton type="text" class="text-caption" />
</div>
</div>
<div
v-if="totalInbox != 0 && !isLoadingInbox"
ref="scrollTargetRef"
style="max-height: 90%; overflow: auto"
>
@ -400,7 +435,11 @@ onMounted(async () => {
</q-infinite-scroll>
</div>
<q-banner rounded class="bg-amber-1 text-center q-mx-sm" v-else>
<q-banner
rounded
class="bg-amber-1 text-center q-mx-sm"
v-else-if="totalInbox === 0 && !isLoadingInbox"
>
<div class="text-yellow-10">
<q-icon
name="mdi-alert-box"

View file

@ -15,7 +15,7 @@ const $q = useQuasar();
const route = useRoute();
const router = useRouter();
const mixin = useCounterMixin();
const { success, messageError, showLoader, hideLoader, dialogConfirm } = mixin;
const { success, messageError, dialogConfirm ,showLoader,hideLoader} = mixin;
const id = ref<string>(
router.currentRoute.value.name === "addTransfer"
@ -23,6 +23,7 @@ const id = ref<string>(
: route.params.id.toString()
); //id path
const isLoading = ref<boolean>(false);
const files = ref<any>(); //
const tranferOrg = ref<string>(""); //
const noteReason = ref<string>(""); //
@ -42,7 +43,7 @@ async function saveData() {
/** ฟังก์ชั่นสร้างขอโอน */
async function createTransfer() {
showLoader();
showLoader()
const formData = new FormData();
formData.append("Organization", tranferOrg.value);
formData.append("Reason", noteReason.value);
@ -51,14 +52,14 @@ async function createTransfer() {
.post(config.API.listtransfer(), formData)
.then((res) => {
router.push(`/transfer/` + res.data.result);
hideLoader()
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
hideLoader()
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/**
@ -66,7 +67,7 @@ async function createTransfer() {
* @param id ไอดของขอม
*/
async function fecthDataTransfer(id: string) {
showLoader();
isLoading.value = true;
await http
.get(config.API.transferByid(id))
.then((res: any) => {
@ -74,13 +75,13 @@ async function fecthDataTransfer(id: string) {
tranferOrg.value = data.organization;
noteReason.value = data.reason;
files.value = data.docs;
isLoading.value = false;
})
.catch((e: any) => {
messageError($q, e);
isLoading.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/**
@ -129,6 +130,7 @@ onMounted(() => {
<div class="row">
<div class="col-12 row q-col-gutter-sm">
<q-input
v-if="!isLoading"
:class="
routeName != 'addTransfer' ? 'col-12' : 'col-12 inputgreen'
"
@ -140,8 +142,11 @@ onMounted(() => {
:readonly="routeName != 'addTransfer'"
:rules="[(val:string) => !!val || `${'กรุณากรอกหน่วยงานที่ขอโอนไป'}`]"
/>
<div class="col-12" v-else>
<q-skeleton type="QInput" height="40px" />
</div>
<q-input
v-if="!isLoading"
:class="
routeName != 'addTransfer' ? 'col-12' : 'col-12 inputgreen'
"
@ -154,7 +159,9 @@ onMounted(() => {
:readonly="routeName != 'addTransfer'"
:rules="[(val:string) => !!val || `${'กรุณากรอกเหตุผล'}`]"
/>
<div class="col-12" v-else>
<q-skeleton type="QInput" height="120px" />
</div>
<div class="col-12 row" v-if="routeName == 'addTransfer'">
<q-file
v-model="files"

View file

@ -20,8 +20,7 @@ const mixin = useCounterMixin();
const transferData = useTransferDataStore();
const { statusText } = transferData;
const { date2Thai, messageError, showLoader, hideLoader, onSearchDataTable } =
mixin;
const { date2Thai, messageError, onSearchDataTable } = mixin;
const pagination = ref({
sortBy: "desc",
@ -30,6 +29,7 @@ const pagination = ref({
rowsPerPage: 10,
});
const isLoading = ref<boolean>(false);
const rows = ref<TransferMain[]>([]);
const rowsData = ref<TransferMain[]>([]);
const filter = ref<string>("");
@ -120,7 +120,7 @@ const columns = ref<QTableProps["columns"]>([
//
async function fecthListTransfer() {
showLoader();
isLoading.value = true;
await http
.get(config.API.listUserTransfer())
.then((res) => {
@ -139,12 +139,11 @@ async function fecthListTransfer() {
}));
rows.value = listData;
rowsData.value = listData;
isLoading.value = false;
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -251,27 +250,13 @@ onMounted(async () => {
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
@ -345,4 +330,5 @@ onMounted(async () => {
</div>
</div>
</template>
<style scoped lang="scss"></style>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { is, useQuasar } from "quasar";
import type { QForm, QTableProps } from "quasar";
import { useRouter, useRoute } from "vue-router";
@ -20,6 +20,8 @@ import Dialog from "@/modules/03_retire/views/DialogRetire.vue";
import Header from "@/components/DialogHeader.vue";
import Workflow from "@/components/Workflow/Main.vue";
const $q = useQuasar();
const route = useRoute();
const router = useRouter();
@ -44,6 +46,7 @@ const id = ref<string>(
? route.params.id.toString()
: ""
); // id path
const isLoad = ref<boolean>(false);
const rowsApprover = ref<RowsType>();
const myform = ref<QForm | null>(null); //form
const tranferOrg = ref(""); //
@ -201,7 +204,7 @@ function cancelResing() {
* @param id ไอดของขอม
*/
async function fectDataresign(id: string) {
showLoader();
isLoad.value = true;
await http
.get(config.API.resingByidType(link.value, id))
.then((res) => {
@ -225,13 +228,12 @@ async function fectDataresign(id: string) {
};
files.value = data.docs;
dataDetail.value = data;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/**
@ -318,6 +320,7 @@ onMounted(async () => {
<div class="col-12 row q-col-gutter-sm q-pa-md">
<q-input
v-if="!isLoad"
:class="
routeName !== 'AddRetire'
? 'col-md-9 col-xs-12'
@ -332,7 +335,9 @@ onMounted(async () => {
:readonly="routeName != 'AddRetire'"
:rules="[(val:string) => !!val || `${'กรุณากรอกสถานที่ยื่นขอลาออกจากราชการ'}`]"
/>
<div class="col-md-9 col-xs-12 inputgreen" v-else>
<q-skeleton type="QInput" height="40px" />
</div>
<!-- <datepicker
:class="
routeName !== 'AddRetire'
@ -383,6 +388,7 @@ onMounted(async () => {
</datepicker> -->
<datepicker
v-if="!isLoad"
:class="
routeName !== 'AddRetire'
? 'col-md-3 col-xs-12'
@ -428,7 +434,11 @@ onMounted(async () => {
</q-input>
</template>
</datepicker>
<div v-else class="col-md-3 col-xs-12">
<q-skeleton type="QInput" height="40px" />
</div>
<q-select
v-if="!isLoad"
v-model="noteReason"
:class="
routeName !== 'AddRetire' ? 'col-12' : 'col-12 inputgreen'
@ -448,6 +458,9 @@ onMounted(async () => {
]"
>
</q-select>
<div v-else class="col-12">
<q-skeleton type="QInput" height="40px" />
</div>
<q-input
:class="
routeName !== 'AddRetire' ? 'col-12' : 'col-12 inputgreen'
@ -604,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">
@ -647,7 +662,6 @@ onMounted(async () => {
</q-card>
</div>
<!-- ผลการพจารณาของผอำนาจ -->
<div class="col-12 row" v-if="routeName != 'AddRetire'">
<q-card bordered class="row col-12 text-dark q-mt-sm">
<div
@ -662,7 +676,7 @@ onMounted(async () => {
<div class="col-12 row bg-white q-col-gutter-md">
<div class="col-xs-6 row items-start">
<div class="col-12 text-top"> - นามสก</div>
<div class="col-12 text-detail">
<div class="col-12 text-detail" v-if="!isLoad">
{{
rowsApprover &&
rowsApprover.approvers &&
@ -671,10 +685,11 @@ onMounted(async () => {
: "-"
}}
</div>
<q-skeleton v-else type="text" width="150px" />
</div>
<div class="col-xs-6 row items-start">
<div class="col-12 text-top">สถานะ</div>
<div class="col-12 text-detail">
<div v-if="!isLoad" class="col-12 text-detail">
{{
rowsApprover &&
rowsApprover.approvers &&
@ -685,12 +700,13 @@ onMounted(async () => {
: "-"
}}
</div>
<q-skeleton v-else type="text" width="150px" />
</div>
<div class="col-xs-6 row items-start">
<div class="col-12 text-top">
นสดทายทบย
</div>
<div class="col-12 text-detail">
<div v-if="!isLoad" class="col-12 text-detail">
{{
rowsApprover &&
rowsApprover.approvers &&
@ -701,12 +717,13 @@ onMounted(async () => {
: "-"
}}
</div>
<q-skeleton v-else type="text" width="150px" />
</div>
<div class="col-xs-12 row items-start">
<div class="col-12 text-top">
ความคดเหนและเหตผล
</div>
<div class="col-12 text-detail">
<div v-if="!isLoad" class="col-12 text-detail">
{{
rowsApprover &&
rowsApprover.approvers &&
@ -715,6 +732,7 @@ onMounted(async () => {
: "-"
}}
</div>
<q-skeleton v-else type="text" width="150px" />
</div>
</div>
</div>
@ -760,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">
@ -803,7 +823,6 @@ onMounted(async () => {
</q-card>
</div>
<!-- ผลการพจารณาของผอำนาจ -->
<div class="col-12 row" v-if="routeName != 'AddRetire'">
<q-card bordered class="row col-12 text-dark q-mt-sm">
<div

View file

@ -20,11 +20,13 @@ const router = useRouter();
const link = ref<string>("");
const dataStore = useDataStore();
const mixin = useCounterMixin();
const { date2Thai, messageError, showLoader, hideLoader } = mixin;
const { date2Thai, messageError, onSearchDataTable } = mixin;
const RestData = useRestDataStore();
const { statusText } = RestData; //Func status to text
const isLoad = ref<boolean>(false);
const rows = ref<MainList[]>([]);
const rowsData = ref<MainList[]>([]);
const filter = ref<string>("");
const pagination = ref({
sortBy: "desc",
@ -91,11 +93,12 @@ const columns = ref<QTableProps["columns"]>([
/** ดึงข้อมูล */
async function fectListleave() {
isLoad.value = true;
await http
.get(config.API.listUserByType(link.value))
.then(async (res) => {
let data = await res.data.result;
rows.value = data.map((e: MainListResponse) => ({
const list = data.map((e: MainListResponse) => ({
id: e.id,
placeLeave: e.location,
dateStartLeave: date2Thai(e.sendDate),
@ -103,9 +106,13 @@ async function fectListleave() {
status: e.status,
statustext: statusText(e.status),
}));
rowsData.value = list;
rows.value = list;
isLoad.value = false;
})
.catch((e: any) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {});
}
@ -117,10 +124,13 @@ async function clickAdd() {
router.push(`/retire/add`);
}
/** ทำก่อน mounted */
onBeforeMount(() => {
showLoader();
});
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
rowsData.value,
columns.value ? columns.value : []
);
}
/**
* เรยกฟงกนทงหมดตอนเรยกใชไฟล
@ -128,7 +138,6 @@ onBeforeMount(() => {
onMounted(async () => {
link.value = await dataStore.getProFileType();
await fectListleave();
hideLoader();
});
</script>
<template>
@ -161,15 +170,10 @@ onMounted(async () => {
debounce="300"
placeholder="ค้นหา"
style="max-width: 200px"
@keydown.enter.prevent="onSearch"
>
<template v-slot:append>
<q-icon v-if="filter == ''" name="search" />
<q-icon
v-if="filter !== ''"
name="clear"
class="cursor-pointer"
@click="filter = ''"
/>
<q-icon name="search" />
</template>
</q-input>
<!-- แสดงคอลมนใน table -->
@ -193,7 +197,7 @@ onMounted(async () => {
</div>
<div>
<d-table
flat
fla
bordered
dense
row-key="id"
@ -202,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

View file

@ -26,7 +26,7 @@ import DialogDetail from "@/modules/05_leave/components/DialogDetail.vue";
const $q = useQuasar();
const store = useLeaveStore();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, monthYear2Thai } = mixin;
const { messageError, monthYear2Thai } = mixin;
const emit = defineEmits(["update:dateYear"]);
const mainData = ref<DataCalendar[]>([]);
@ -37,10 +37,10 @@ const leaveId = ref<string>("");
/** filter calendar left */
const filterLists = ref<any>([]);
const filterVal = ref<any>([keycloakId.value]);
const isLoading = ref<boolean>(false);
const isLoadingHoliday = ref<boolean>(false);
/**
* Option ของปฏ
*/
/** Option ของปฏิทิน */
const fullCalendar = ref<any>(); //ref calendar
const calendarOptions = ref<any>({
plugins: [
@ -76,6 +76,7 @@ const dateMonth = ref<DataDateMonthObject>({
/** function เรียกข้อมูล calendar*/
async function fetchDataCalendar() {
isLoading.value = true;
await http
.post(config.API.leaveCalendar(), {
year: dateMonth.value.year,
@ -119,6 +120,9 @@ async function fetchDataCalendar() {
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoading.value = false;
});
}
@ -126,6 +130,7 @@ async function fetchDataCalendar() {
* fetch นหยดในปฏ
*/
async function fetchData() {
isLoadingHoliday.value = true;
await http
.get(
config.API.listHolidayHistoryYearMonth(
@ -154,6 +159,9 @@ async function fetchData() {
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoadingHoliday.value = false;
});
}
@ -193,7 +201,6 @@ async function updateMonth() {
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
}
@ -215,7 +222,6 @@ async function onClickClose() {
watch(
() => filterVal.value,
async () => {
showLoader();
const eventData = filterVal.value.map((item: any) => {
return mainData.value
.filter(
@ -236,14 +242,13 @@ watch(
const allEventData = [].concat(...eventData);
calendarOptions.value.events = allEventData;
await fetchData();
hideLoader();
}
);
/**Hook */
onMounted(async () => {
try {
showLoader();
isLoading.value = true;
// keycloakId
const user = await tokenParsed();
keycloakId.value = await (user ? user.sub : "");
@ -253,7 +258,7 @@ onMounted(async () => {
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
isLoading.value = false;
}
});
</script>
@ -262,7 +267,19 @@ onMounted(async () => {
<div class="row">
<div class="col-xs-12 col-md-3 q-mt-sm q-pr-sm row">
<q-card class="col-12" flat bordered>
<q-scroll-area style="height: 38vw">
<q-card-section v-if="isLoading">
<q-item>
<q-item-section avatar>
<q-skeleton type="QToggle" height="20px" width="25px" />
</q-item-section>
<q-item-section>
<q-skeleton type="text" class="text-subtitle1" />
</q-item-section>
</q-item>
</q-card-section>
<q-scroll-area style="height: 38vw" v-else>
<div class="q-gutter-sm col-12">
<q-list class="rounded-borders q-pt-sm" dense>
<q-item
@ -333,7 +350,13 @@ onMounted(async () => {
</q-card>
<div class="main-content">
<q-skeleton
height="100%"
square
v-if="isLoading || isLoadingHoliday"
/>
<FullCalendar
v-else
ref="fullCalendar"
class="demo-app-calendar"
:options="calendarOptions"

View file

@ -164,6 +164,7 @@ const formDataCancle = reactive<FromCancelDetail>({
leaveRangeEnd: "",
leaveDirectorComment: "",
});
const isLoading = ref<boolean>(false);
/** form ขอยกเลิก*/
const formDelete = reactive<FormDelete>({
@ -187,7 +188,7 @@ const formDeleteRef: FormDeleteRef = {
* @param id การลา
*/
async function fetchDataDetail(id: string) {
showLoader();
isLoading.value = true;
await http
.get(config.API.leaveUserId(id), {})
.then((res) => {
@ -280,7 +281,7 @@ async function fetchDataDetail(id: string) {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -308,10 +309,7 @@ function checkLeaveType(leaveTypeId: string) {
checkForm.value = "FormHajj";
} else if (type === "LV-007") {
checkForm.value = "FormCheckSelect";
} else if (
type === "LV-008" &&
formData.leaveSubTypeName === "ศึกษาต่อ"
) {
} else if (type === "LV-008" && formData.leaveSubTypeName === "ศึกษาต่อ") {
checkForm.value = "FormStudy";
} else if (
(type === "LV-008" && formData.leaveSubTypeName === "ฝึกอบรม") ||
@ -334,7 +332,7 @@ function checkLeaveType(leaveTypeId: string) {
* @param id ยกเลกการลา
*/
async function fetchDataCancelDetail(id: string) {
showLoader();
isLoading.value = true;
await http
.get(config.API.leaveCancelById(id))
.then((res) => {
@ -362,7 +360,7 @@ async function fetchDataCancelDetail(id: string) {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -401,7 +399,8 @@ async function onSubmit() {
formData.append("doc", formDelete.doc);
await http
.post(config.API.leaveCancelById(id), formData)
.then(() => {
.then(async () => {
await props.fetchDataTable?.();
success($q, "บันทึกข้อมูลสำเร็จ");
props.onClickClose?.();
})
@ -409,7 +408,6 @@ async function onSubmit() {
messageError($q, err);
})
.finally(() => {
props.fetchDataTable?.();
hideLoader();
});
}
@ -443,8 +441,13 @@ watch(
/>
<q-separator />
<q-card-section v-if="isLoading">
<div v-for="i in 10" :key="i">
<q-skeleton type="text" class="text-subtitle1" />
</div>
</q-card-section>
<q-card-section class="scroll" style="max-height: 60vh">
<q-card-section v-else class="scroll" style="max-height: 60vh">
<div class="row">
<div
flat
@ -571,6 +574,7 @@ watch(
label="ยืนยัน"
unelevated
color="secondary"
:loading="isLoading"
@click="onClickSave"
/>
</q-card-section>
@ -583,7 +587,12 @@ watch(
/>
<q-separator />
<q-card-section class="q-p-md row q-gutter-y-md">
<q-card-section v-if="isLoading">
<div v-for="i in 10" :key="i">
<q-skeleton type="text" class="text-subtitle1" />
</div>
</q-card-section>
<q-card-section class="q-p-md row q-gutter-y-md" v-else>
<div flat class="col-12">
<div class="col-12 q-col-gutter-sm row items-center"></div>
<FormCancel :data="formDataCancle" />

View file

@ -15,8 +15,7 @@ const typeForm = defineModel<string>("type", { required: true });
const $q = useQuasar();
const dataStore = useLeaveStore();
const mixin = useCounterMixin();
const { date2Thai, messageError, convertDateToAPI, showLoader, hideLoader } =
mixin;
const { date2Thai, messageError, convertDateToAPI } = mixin;
const edit = ref<boolean>(true);
const leaveDocumentRef = ref<any>(null);
@ -66,6 +65,8 @@ const leaveNumberRef = ref<object | null>(null);
const leaveAddressRef = ref<object | null>(null);
const leaveDetailRef = ref<object | null>(null);
const isLoadLeaveDate = ref<boolean>(false);
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = {
leaveWrote: leaveWroteRef,
@ -149,7 +150,7 @@ const checkDate = computed(() => {
// const totalCheck = ref<number | null>(null);
async function fetchCheck() {
if (formDataSick.leaveStartDate && formDataSick.leaveEndDate) {
showLoader();
isLoadLeaveDate.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -177,11 +178,10 @@ async function fetchCheck() {
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
hideLoader();
leaveDocumentRef.value.resetValidation();
isLoadLeaveDate.value = false;
});
}
}
@ -425,6 +425,7 @@ onMounted(() => {
v-model="formDataSick.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadLeaveDate"
>
<template v-slot:hint>
<span style="color: red">
@ -626,8 +627,10 @@ onMounted(() => {
:disable="!isLeave"
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadLeaveDate"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
@ -637,8 +640,10 @@ onMounted(() => {
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadLeaveDate"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</q-card-actions>
</q-form>
</template>

View file

@ -13,14 +13,7 @@ import type { FormRef } from "@/modules/05_leave/interface/request/BirthForm";
const $q = useQuasar();
const dataStore = useLeaveStore();
const mixin = useCounterMixin();
const {
date2Thai,
dateToISO,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const { date2Thai, messageError, convertDateToAPI } = mixin;
const edit = ref<boolean>(true);
const leaveId = ref<string>("");
@ -45,6 +38,8 @@ const props = defineProps({
},
});
const isLoadCheck = ref<boolean>(false);
/** ข้อมูล v-model ของฟอร์ม */
const formDataBirth = reactive<any>({
type: dataStore.typeId,
@ -145,14 +140,10 @@ const checkDate = computed(() => {
}
});
/**
* check าลาไดไหม จาก api
* @param formData
*/
// const totalCheck = ref<number | null>(null);
/** ตรวจสอบวันลา */
async function fetchCheck() {
if (formDataBirth.leaveStartDate && formDataBirth.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
const checkDate = computed(() => {
if (
convertDateToAPI(formDataBirth.leaveEndDate) ==
@ -163,9 +154,7 @@ async function fetchCheck() {
return false;
}
});
// console.log("checkDate.value", checkDate.value);
// console.log("formDataBirth.leaveRangeEnd", formDataBirth.leaveRangeEnd);
// console.log("formDataBirth.leaveRange", formDataBirth.leaveRange);
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -176,11 +165,9 @@ async function fetchCheck() {
? formDataBirth.leaveRange
: formDataBirth.leaveRangeEnd,
})
.then((res: any) => {
hideLoader();
.then((res) => {
const data = res.data.result;
formDataBirth.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
reasonLeave.value =
data.message != ""
? data.message
@ -189,10 +176,11 @@ async function fetchCheck() {
: "ช่วงวันลาที่ระบุไม่ถูกต้อง";
isLeave.value = formDataBirth.leaveTotal > 0 ? data.isLeave : false;
})
.catch((e: any) => {
hideLoader();
// totalCheck.value = null;
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -433,6 +421,7 @@ onMounted(() => {
v-model="formDataBirth.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -596,30 +585,31 @@ onMounted(() => {
<div class="row col-12 q-pt-md">
<q-space />
<!-- <div v-if="totalCheck == 0" class="text-red q-mr-sm">**จำนวนวันลาของท่านไม่ถูกต้อง หรือวันที่ยื่นลาของท่านตรงกับวันหยุด</div> -->
<q-btn
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
:disable="!isLeave"
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -1,7 +1,6 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch } from "vue";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
@ -14,17 +13,8 @@ import type { FormRef } from "@/modules/05_leave/interface/request/HelpWifeForm"
const $q = useQuasar();
const dataStore = useLeaveStore();
const mixin = useCounterMixin();
const {
date2Thai,
calculateDurationYmd,
dateToISO,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const { date2Thai, messageError, convertDateToAPI } = mixin;
const leaveText = ref<string>("");
const edit = ref<boolean>(true);
const leaveId = ref<string>("");
@ -161,14 +151,12 @@ const checkDate = computed(() => {
}
});
/**
* check าลาไดไหม จาก api
* @param formData
*/
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
/** fetchCheck ว่าลาได้ไหม จาก api */
async function fetchCheck() {
if (formDataHelpWife.leaveStartDate && formDataHelpWife.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -184,8 +172,6 @@ async function fetchCheck() {
const data = res.data.result;
formDataHelpWife.leaveTotal =
data.totalDate - data.sumDateWork - data.sumDateHoliday;
// totalCheck.value =
// data.totalDate - data.sumDateWork - data.sumDateHoliday;
reasonLeave.value =
data.message != ""
? data.message
@ -193,23 +179,21 @@ async function fetchCheck() {
? "จำนวนวันลาเกินที่กำหนด"
: "ช่วงวันลาที่ระบุไม่ถูกต้อง";
isLeave.value = formDataHelpWife.leaveTotal > 0 ? data.isLeave : false;
hideLoader();
})
.catch((e: any) => {
.catch((e) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
watch(
() => props.data,
async () => {
if (props.data) {
// totalCheck.value = null;
formDataHelpWife.leaveWrote = props.data.leaveWrote;
formDataHelpWife.wifeDayName = props.data.wifeDayName;
formDataHelpWife.wifeDayDateBorn = props.data.wifeDayDateBorn;
@ -229,7 +213,6 @@ watch(
/**Hook */
onMounted(async () => {
if (props.data) {
// totalCheck.value = null;
formDataHelpWife.leaveWrote = props.data.leaveWrote;
formDataHelpWife.wifeDayName = props.data.wifeDayName;
formDataHelpWife.wifeDayDateBorn = props.data.wifeDayDateBorn;
@ -438,6 +421,7 @@ onMounted(async () => {
v-model="formDataHelpWife.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -656,24 +640,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
:disable="!isLeave"
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -14,14 +14,7 @@ import type { DataOption } from "@/modules/14_IDP/interface/Main";
const $q = useQuasar();
const dataStore = useLeaveStore();
const mixin = useCounterMixin();
const {
date2Thai,
dateToISO,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const { date2Thai, messageError, convertDateToAPI } = mixin;
const edit = ref<boolean>(true);
const leaveId = ref<string>("");
@ -164,10 +157,11 @@ const checkDate = computed(() => {
}
});
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (formDataVacation.leaveStartDate && formDataVacation.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -183,8 +177,6 @@ async function fetchCheck() {
const data = res.data.result;
formDataVacation.leaveTotal =
data.totalDate - data.sumDateWork - data.sumDateHoliday;
// totalCheck.value =
// data.totalDate - data.sumDateWork - data.sumDateHoliday;
reasonLeave.value =
data.message != ""
@ -193,12 +185,12 @@ async function fetchCheck() {
? "จำนวนวันลาเกินที่กำหนด"
: "ช่วงวันลาที่ระบุไม่ถูกต้อง";
isLeave.value = formDataVacation.leaveTotal > 0 ? data.isLeave : false;
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -207,7 +199,6 @@ watch(
() => props.data,
() => {
if (props.data) {
// totalCheck.value = null;
formDataVacation.leaveWrote = props.data.leaveWrote;
formDataVacation.restDayOldTotal = props.data.restDayOldTotal;
formDataVacation.restDayCurrentTotal = props.data.restDayCurrentTotal;
@ -456,6 +447,7 @@ onMounted(() => {
v-model="formDataVacation.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -630,30 +622,31 @@ onMounted(() => {
<q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md items-center">
<q-space />
<!-- <div v-if="totalCheck == 0" class="text-red q-mr-sm">**จำนวนวันลาของท่านไม่ถูกต้อง หรือวันที่ยื่นลาของท่านตรงกับวันหยุด</div> -->
<q-btn
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
:disable="!isLeave"
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -13,8 +13,7 @@ import type { OrdinationForm } from "@/modules/05_leave/interface/request/AddAbs
const $q = useQuasar();
const dataStore = useLeaveStore();
const mixin = useCounterMixin();
const { date2Thai, messageError, convertDateToAPI, showLoader, hideLoader } =
mixin;
const { date2Thai, messageError, convertDateToAPI } = mixin;
const edit = ref<boolean>(true);
const leaveId = ref<string>("");
/** รับ props มาจากหน้าหลัก */
@ -179,14 +178,12 @@ const checkDate = computed(() => {
}
});
/**
* check าลาไดไหม จาก api
* @param formData
*/
// const totalCheck = ref<number|null>(null)
const isLoadCheck = ref<boolean>(false);
/** check ว่าลาได้ไหม จาก api*/
async function fetchCheck() {
if (formDataOrdination.leaveStartDate && formDataOrdination.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -201,7 +198,6 @@ async function fetchCheck() {
.then((res: any) => {
const data = res.data.result;
formDataOrdination.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
reasonLeave.value =
data.message != ""
? data.message
@ -210,12 +206,12 @@ async function fetchCheck() {
: "ช่วงวันลาที่ระบุไม่ถูกต้อง";
isLeave.value =
formDataOrdination.leaveTotal > 0 ? data.isLeave : false;
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -488,6 +484,7 @@ onMounted(async () => {
v-model="formDataOrdination.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -843,24 +840,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -17,10 +17,8 @@ const {
date2Thai,
calculateDurationYmd,
messageError,
dateToISO,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const edit = ref<boolean>(true);
@ -79,7 +77,6 @@ const formRef: HajiForm = {
};
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>("");
const fileDocDataUpload = ref<File[]>([]);
const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => {
@ -145,10 +142,10 @@ const checkDate = computed(() => {
}
});
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (formDataHaji.leaveStartDate && formDataHaji.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -161,9 +158,7 @@ async function fetchCheck() {
})
.then((res: any) => {
const data = res.data.result;
// isLeave.value = data.isLeave;
formDataHaji.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
leaveText.value = calculateDurationYmd(
convertDateToAPI(formDataHaji.leaveStartDate),
convertDateToAPI(formDataHaji.leaveEndDate)
@ -175,12 +170,12 @@ async function fetchCheck() {
? "จำนวนวันลาเกินที่กำหนด"
: "ช่วงวันลาที่ระบุไม่ถูกต้อง";
isLeave.value = formDataHaji.leaveTotal > 0 ? data.isLeave : false;
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -415,6 +410,7 @@ onMounted(async () => {
v-model="formDataHaji.leaveTotal"
label="จำนวนวันที่ลา (วัน)"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -589,24 +585,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -13,15 +13,8 @@ import type { MilitaryForm } from "@/modules/05_leave/interface/request/AddAbsen
const dataStore = useLeaveStore();
const $q = useQuasar();
const mixin = useCounterMixin();
const {
date2Thai,
calculateDurationYmd,
dateToISO,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const { date2Thai, calculateDurationYmd, messageError, convertDateToAPI } =
mixin;
const edit = ref<boolean>(true);
const leaveId = ref<string>("");
const leaveText = ref<string>("");
@ -163,14 +156,12 @@ const checkDate = computed(() => {
}
});
/**
* check าลาไดไหม จาก api
* @param formData
*/
// const totalCheck = ref<number|null>(null)
const isLoadCheck = ref<boolean>(false);
/** check ว่าลาได้ไหม จาก api*/
async function fetchCheck() {
if (formDataMilitary.leaveStartDate && formDataMilitary.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -186,35 +177,22 @@ async function fetchCheck() {
const data = res.data.result;
isLeave.value = data.isLeave;
formDataMilitary.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
leaveText.value = calculateDurationYmd(
convertDateToAPI(formDataMilitary.leaveStartDate),
convertDateToAPI(formDataMilitary.leaveEndDate)
);
reasonLeave.value =
data.message != "" ? data.message : "จำนวนวันลาเกินที่กำหนด";
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
// /**
// * function LeaveTotal
// */
// function updateLeaveTotal() {
// const newLeaveTotal = calculateDurationYmd(
// formDataMilitary.leaveStartDate,
// formDataMilitary.leaveEndDate
// );
// formDataMilitary.leaveTotal = newLeaveTotal;
// }
watch(
() => props.data,
async () => {
@ -463,6 +441,7 @@ onMounted(async () => {
v-model="leaveText"
label="จำนวนวันที่ลา"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -675,24 +654,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -16,12 +16,9 @@ const mixin = useCounterMixin();
const {
date2Thai,
calculateDurationYmd,
dateToISO,
messageError,
arabicNumberToText,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const leaveText = ref<string>("");
@ -182,10 +179,10 @@ const checkDate = computed(() => {
}
});
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (formDataStudy.leaveStartDate && formDataStudy.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -200,7 +197,7 @@ async function fetchCheck() {
const data = res.data.result;
isLeave.value = data.isLeave;
formDataStudy.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
leaveText.value = calculateDurationYmd(
convertDateToAPI(formDataStudy.leaveStartDate),
convertDateToAPI(formDataStudy.leaveEndDate)
@ -208,27 +205,16 @@ async function fetchCheck() {
reasonLeave.value = data.message
? data.message
: "จำนวนวันลาเกินที่กำหนด";
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null;
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
// /**
// * function LeaveTotal
// */
// function updateLeaveTotal() {
// const newLeaveTotal = calculateDurationYmd(
// formDataStudy.leaveStartDate,
// formDataStudy.leaveEndDate
// );
// formDataStudy.leaveTotal = newLeaveTotal;
// }
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
watch(
() => props.data,
@ -490,6 +476,7 @@ onMounted(async () => {
v-model="leaveText"
label="มีกำหนด"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -828,24 +815,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -19,8 +19,6 @@ const {
calculateDurationYmd,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const leaveText = ref<string>("");
@ -167,10 +165,11 @@ const checkDate = computed(() => {
}
});
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (formDataTrain.leaveStartDate && formDataTrain.leaveEndDate) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -185,7 +184,7 @@ async function fetchCheck() {
const data = res.data.result;
isLeave.value = data.isLeave;
formDataTrain.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
leaveText.value = calculateDurationYmd(
convertDateToAPI(formDataTrain.leaveStartDate),
convertDateToAPI(formDataTrain.leaveEndDate)
@ -193,32 +192,20 @@ async function fetchCheck() {
reasonLeave.value = data.message
? data.message
: "จำนวนวันลาเกินที่กำหนด";
hideLoader();
})
.catch((e: any) => {
// totalCheck.value = null;
messageError($q, e);
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
/**
* function พเดทค LeaveTotal
*/
function updateLeaveTotal() {
const newLeaveTotal = calculateDurationYmd(
formDataTrain.leaveStartDate,
formDataTrain.leaveEndDate
);
formDataTrain.leaveTotal = newLeaveTotal;
}
watch(
() => props.data,
async () => {
if (props.data) {
// totalCheck.value = null;
formDataTrain.leaveWrote = props.data.leaveWrote;
formDataTrain.leaveStartDate = props.data.leaveStartDate;
formDataTrain.leaveEndDate = props.data.leaveEndDate;
@ -470,6 +457,7 @@ onMounted(async () => {
v-model="leaveText"
label="มีกำหนด"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -789,24 +777,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -1,6 +1,5 @@
<script setup lang="ts">
import { ref, reactive, watch, onMounted, computed } from "vue";
import { useRouter } from "vue-router";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
@ -79,8 +78,6 @@ const FormRef: FormRef = {
};
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>("");
const nameFileDraft = ref<string>("");
const fileDocDataUpload = ref<File[]>([]);
const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => {
@ -171,12 +168,13 @@ const checkDate = computed(() => {
* @param formData
*/
const isLeave = ref<boolean>(true);
// const totalCheck = ref<number|null>(null)
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (
formDataWorkInternational.leaveStartDate &&
formDataWorkInternational.leaveEndDate
) {
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -193,7 +191,6 @@ async function fetchCheck() {
const data = res.data.result;
isLeave.value = data.isLeave;
formDataWorkInternational.leaveTotal = data.totalDate;
// totalCheck.value = data.totalDate;
leaveText.value = calculateDurationYmd(
convertDateToAPI(formDataWorkInternational.leaveStartDate),
convertDateToAPI(formDataWorkInternational.leaveEndDate)
@ -203,8 +200,10 @@ async function fetchCheck() {
: "จำนวนวันลาเกินที่กำหนด";
})
.catch((e: any) => {
// totalCheck.value = null;
messageError($q, e);
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -249,17 +248,17 @@ watch(
}
);
watch(
() => formDataWorkInternational.leaveEndDate,
() => {
if (
formDataWorkInternational.leaveStartDate !== null &&
formDataWorkInternational.leaveEndDate !== null
) {
fetchCheck();
}
}
);
// watch(
// () => formDataWorkInternational.leaveEndDate,
// () => {
// if (
// formDataWorkInternational.leaveStartDate !== null &&
// formDataWorkInternational.leaveEndDate !== null
// ) {
// fetchCheck();
// }
// }
// );
/**Hook */
onMounted(async () => {
@ -475,6 +474,7 @@ onMounted(async () => {
v-model="leaveText"
label="มีกำหนด"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -644,24 +644,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</div>
</form>

View file

@ -4,7 +4,6 @@ import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useRouter } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { useLeaveStore } from "@/modules/05_leave/store";
@ -15,15 +14,8 @@ const dataStore = useLeaveStore();
const $q = useQuasar();
const mixin = useCounterMixin();
const {
date2Thai,
calculateDurationYmd,
dateToISO,
messageError,
convertDateToAPI,
showLoader,
hideLoader,
} = mixin;
const { date2Thai, calculateDurationYmd, messageError, convertDateToAPI } =
mixin;
const leaveText = ref<string>("");
const edit = ref<boolean>(true);
@ -209,13 +201,13 @@ const reasonLeave = ref<string>("");
* @param formData
*/
const isLeave = ref<boolean>(true);
// const totalCheck = ref<number | null>(null);
const isLoadCheck = ref<boolean>(false);
async function fetchCheck() {
if (
formDataFollowSpouse.leaveStartDate &&
formDataFollowSpouse.leaveEndDate
) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -241,12 +233,12 @@ async function fetchCheck() {
? data.message
: "จำนวนวันลาเกินที่กำหนด";
checkTotalHistory();
hideLoader();
})
.catch((e: any) => {
messageError($q, e);
// totalCheck.value = null
hideLoader();
})
.finally(() => {
isLoadCheck.value = false;
});
}
}
@ -568,6 +560,7 @@ onMounted(async () => {
v-model="leaveText"
label="เป็นเวลา"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -917,24 +910,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</form>
</template>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { reactive, ref, onMounted, computed, watch } from "vue";
import { useQuasar } from "quasar";
import { is, useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import type { RehabilitationForm } from "@/modules/05_leave/interface/request/AddAbsence";
@ -8,6 +8,7 @@ import { useLeaveStore } from "@/modules/05_leave/store";
import http from "@/plugins/http";
import config from "@/app.config";
import genReport from "@/plugins/genreport";
import { load } from "@/router/loader";
const $q = useQuasar();
const dataStore = useLeaveStore();
@ -125,17 +126,14 @@ const checkDate = computed(() => {
}
});
/**
* check าลาไดไหม จาก api
* @param formData
*/
// const totalCheck = ref<number|null>(null)
const isLoadCheck = ref<boolean>(false);
/** check ว่าลาได้ไหม จาก api */
async function fetchCheck() {
if (
formDataRehabilitation.leaveStartDate &&
formDataRehabilitation.leaveEndDate
) {
showLoader();
isLoadCheck.value = true;
await http
.post(config.API.leaveCheck(), {
type: dataStore.typeId ?? null,
@ -167,7 +165,7 @@ async function fetchCheck() {
// totalCheck.value = null
})
.finally(() => {
hideLoader();
isLoadCheck.value = false;
});
}
}
@ -438,6 +436,7 @@ onMounted(async () => {
v-model="leaveText"
label="เป็นเวลา"
readonly
:loading="isLoadCheck"
>
<template v-slot:hint>
<span style="color: red">
@ -600,24 +599,26 @@ onMounted(async () => {
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
:disable="!isLeave"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นทกแบบราง</q-tooltip>
</q-btn>
<q-btn
v-if="data && statusCheck != 'NEW'"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm()"
><q-tooltip>นใบลา</q-tooltip></q-btn
:loading="isLoadCheck"
>
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</div>
</q-form>

View file

@ -1,5 +1,6 @@
<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";
import config from "@/app.config";
@ -7,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 { useQuasar, type QTableProps } from "quasar";
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: {
@ -24,20 +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 rows = ref<any[]>([]);
const isAct = ref<boolean>(false);
const selected = ref<DataCommander[]>([]);
const search = ref<string>("");
const isLoading = ref<boolean>(false);
const rows = ref<DataCommander[]>([]);
const columns = ref<QTableProps["columns"]>([
{
name: "posNo",
@ -70,30 +65,17 @@ 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() {
showLoader();
isLoading.value = true;
await http
.put(config.API.commanderOperate, {
isAct: isAct.value,
@ -107,37 +89,68 @@ async function getCommander() {
: "employee",
})
.then((res) => {
rows.value = res.data.result.data;
const result = res.data.result;
rows.value = result.data;
pagination.value = {
...pagination.value,
rowsNumber: result.total,
};
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
function updatePagination(newPagination: any) {
pagination.value.page = 1;
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(() => {
dataStore.typeLeave = "";
});
</script>
<template>
@ -223,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"
@ -311,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
@ -321,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"
@ -356,24 +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
@ -410,11 +404,7 @@ onMounted(() => {
:props="props"
>
<div v-if="col.name == 'no'">
{{
(pagination.page - 1) * pagination.rowsPerPage +
props.rowIndex +
1
}}
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}

View file

@ -30,6 +30,7 @@ const year = ref<number>(new Date().getFullYear());
const type = ref<string>("00000000-0000-0000-0000-000000000000");
const status = ref<string>("ALL");
const filter = ref<string>("");
const isLoading = ref<boolean>(false);
/** pagination*/
const maxPage = ref<number>(1);
@ -38,7 +39,7 @@ const pageSize = ref<number>(10);
const total = ref<number>(0);
/** function เรียกข้อมูลการลา*/
async function fetchDataTable() {
showLoader();
isLoading.value = true;
const body = {
year: year.value, //*( .)
type: LeaveData.type, //*Id
@ -59,7 +60,7 @@ async function fetchDataTable() {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -128,10 +129,10 @@ async function onClickClose() {
*/
async function updateFilterTable(y: number, t: string, s: string, k: string) {
if (t && s) {
year.value = await y;
type.value = await t;
status.value = await s;
filter.value = await k;
year.value = y;
type.value = t;
status.value = s;
filter.value = k;
await fetchDataTable();
}
}
@ -142,7 +143,7 @@ async function updateFilterTable(y: number, t: string, s: string, k: string) {
* @param ps แถวตอหน
*/
async function updatePagination(p: number, ps: number) {
(page.value = await p), (pageSize.value = await ps);
(page.value = p), (pageSize.value = ps);
await fetchDataTable();
}
@ -168,15 +169,8 @@ function convert(val: any) {
* เรยกฟงกนทงหมดตอนเรยกใชไฟล
*/
onMounted(async () => {
try {
showLoader();
await fectOptionType();
await fetchDataTable();
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
await fectOptionType();
await fetchDataTable();
});
</script>
<template>
@ -194,6 +188,7 @@ onMounted(async () => {
:pageSize="pageSize"
:leaveType="leaveType"
:total="total"
:isloadingData="isLoading"
>
<template #columns="props">
<q-tr :props="props" class="cursor-pointer">
@ -202,7 +197,7 @@ onMounted(async () => {
:props="props"
@click="onClickView(props.row.id, props.row.status)"
>
{{ (page - 1) * pageSize + props.rowIndex + 1 }}
{{ props.rowIndex + 1 }}
</q-td>
<q-td
key="leaveTypeName"

View file

@ -2,6 +2,7 @@
import { ref, useAttrs, watch } from "vue";
import { useQuasar } from "quasar";
import type { PropsTable } from "@/interface/PropsTable";
import { useLeaveStore } from "@/modules/05_leave/store";
const $q = useQuasar();
@ -15,7 +16,6 @@ const props = defineProps({
pass: Number,
notpass: Number,
total: Number,
name: String,
icon: String,
inputvisible: Array,
@ -34,6 +34,10 @@ const props = defineProps({
type: Object,
require: true,
},
isloadingData: {
type: Boolean,
default: false,
},
});
/**
@ -48,17 +52,28 @@ const emit = defineEmits([
const table = ref<any>(null);
/**
* งค pagination
*/
/** ตั้งค่า 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>("");
@ -84,15 +99,17 @@ function updatePagination(p: number, ps: number) {
emit("update:Pagination", p, ps);
}
/** function updatePageSize*/
function updatePageSize(newPageSize: any) {
currentPage.value = 1;
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([() => currentPage.value, () => pagination.value.rowsPerPage], () => {
updatePagination(currentPage.value, pagination.value.rowsPerPage);
});
</script>
<template>
@ -245,8 +262,9 @@ watch([() => currentPage.value, () => pagination.value.rowsPerPage], () => {
dense
:rows-per-page-options="[10, 25, 50, 100]"
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">
@ -255,18 +273,6 @@ watch([() => currentPage.value, () => pagination.value.rowsPerPage], () => {
</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
></q-pagination>
</template>
<template #body="props">
<slot v-bind="props" name="columns"></slot>
</template>

View file

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

View file

@ -28,6 +28,7 @@ export const useLeaveStore = defineStore("Leave", () => {
const fiscalYearyear = ref<Number | null>(new Date().getFullYear());
const rows = ref<ListLeaveTable[]>([]);
const leaveTypeData = ref<TypeLeave[]>([]);
const isLoadingProfile = ref<boolean>(false); // สถานะการโหลดข้อมูลโปรไฟล์
/**
* function Table
@ -307,13 +308,15 @@ export const useLeaveStore = defineStore("Leave", () => {
//ดึงข้อมูล profile จาก API
async function fetchProfile() {
showLoader();
// showLoader();
isLoadingProfile.value = true;
await http
.post(config.API.leaveProfile(), { type: typeId.value })
.then((res: any) => {
const data = res.data.result;
dateSendLeave.value = data.dateSendLeave;
leaveTypeName.value = data.leaveTypeName;
typeLeave.value = data.leaveTypeName;
fullName.value = data.fullName;
positionName.value = data.positionName;
positionLevelName.value = data.positionLevelName;
@ -345,7 +348,8 @@ export const useLeaveStore = defineStore("Leave", () => {
console.log(e);
})
.finally(() => {
hideLoader();
// hideLoader();
isLoadingProfile.value = false;
});
}
@ -474,5 +478,6 @@ export const useLeaveStore = defineStore("Leave", () => {
converstType,
fetchLeaveTypeData,
isLoadingProfile,
};
});

View file

@ -106,6 +106,8 @@ function filterOptionFn(val: string, update: Function) {
}
onMounted(async () => {
dataStore.typeLeave = "";
if (dataStore.options.length == 0) {
await fectOptionType();
}
@ -209,11 +211,92 @@ onMounted(async () => {
อมลการลา
</div>
</div>
<FormPart2 :model="model" />
<q-card
bordered
class="q-pa-md bg-grey-1"
v-if="dataStore.isLoadingProfile"
>
<div class="row q-col-gutter-sm">
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
</div>
</div>
<div class="col-md-6 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-6 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
<div class="col-md-4 col-xs-12">
<q-skeleton height="40px" />
</div>
</div>
</q-card>
<FormPart2 v-else :model="model" />
</div>
</div>
<div class="col-12">
<div class="col-12" v-if="dataStore.isLoadingProfile">
<div style="display: flex; align-items: center">
<q-icon
name="mdi-numeric-3-circle"
size="20px"
color="primary"
/>
<div class="q-pl-sm text-weight-bold text-dark">กรอกขอม</div>
</div>
<q-card bordered class="q-pa-md bg-grey-1">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-skeleton height="40px" />
</div>
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-md-3 col-xs-6">
<q-skeleton height="40px" />
</div>
<div class="col-md-3 col-xs-6">
<q-skeleton height="40px" />
</div>
</div>
</div>
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-md-3 col-xs-12">
<q-skeleton height="40px" />
</div>
</div>
</div>
<div class="col-12">
<q-skeleton height="40px" />
</div>
<div class="col-12">
<q-skeleton height="120px" />
</div>
<div class="col-12">
<q-skeleton height="40px" />
</div>
</div>
</q-card>
</div>
<div class="col-12" v-else>
<SickForm
v-if="model === 'LV-001' || model === 'LV-002'"
v-model:type="model"

View file

@ -320,6 +320,8 @@ async function fectOptionType() {
* เรยกใชงาน fetchData เพอดงขอม
*/
onMounted(async () => {
dataStore.typeLeave = "";
if (dataStore.options.length == 0) {
fectOptionType();
}

View file

@ -118,11 +118,11 @@ const columns = ref<QTableProps["columns"]>([
},
]);
const isloading = ref<boolean>(false);
const isloadingSummary = ref<boolean>(false);
/** function เรียกข้อมูลตารางสถิติการลา*/
async function fetchStatsTable() {
isloading.value = true;
isloadingSummary.value = true;
await http
.get(config.API.leaveStats())
.then((res) => {
@ -171,11 +171,12 @@ async function fetchStatsTable() {
leaveCountReject: e.leaveCountReject,
leaveCountDelete: e.leaveCountDelete,
}));
isloading.value = false;
})
.catch((err) => {
messageError($q, err);
isloading.value = true;
})
.finally(() => {
isloadingSummary.value = false;
});
}
@ -215,7 +216,7 @@ onMounted(async () => {
<div class="col-xs-12 col-sm-12 col-md-11 row">
<!-- สถการลา -->
<div class="col-12 row q-pb-sm">
<q-card bordered class="col-12 row" v-if="!isloading">
<q-card bordered class="col-12 row" v-if="!isloadingSummary">
<div class="row col-12 items-center q-px-md q-py-sm">
<div class="text-weight-bold">สถการลา</div>
<q-space />
@ -278,6 +279,7 @@ onMounted(async () => {
</q-card>
</div>
</div>
<div class="col-6 row">
<div
bordered

View file

@ -198,7 +198,7 @@ const formDataStep1 = ref<PersonInformation>();
* @param id id ประเม
*/
async function fetchDataStep1(id: string) {
showLoader();
// showLoader();
showLoadStatus.value = false;
await http
.get(config.API.evaluationCheckspecByid(id))
@ -211,9 +211,6 @@ async function fetchDataStep1(id: string) {
})
.finally(() => {
showLoadStatus.value = true;
setTimeout(() => {
hideLoader();
}, 3000);
});
}
@ -581,7 +578,9 @@ async function saveStep7() {
.then(() => {
route.params.id && fetchCheckStep(route.params.id.toString());
})
.catch(() => {})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { reactive, onMounted } from "vue";
import { reactive, ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import { useQuasar } from "quasar";
@ -25,11 +25,12 @@ const formData = reactive<FormCommandSe>({
commanderAbovePosition: "",
});
/**
* นยนการบนทกขอม
*/
const isLoading = ref(false);
/** ยืนยันการบันทึกข้อมูล */
function onSubmit() {
dialogConfirm($q, () => {
dialogConfirm($q, async () => {
showLoader();
const body = {
...formData,
citizenId: dataPerson.formData.citizenId,
@ -40,8 +41,7 @@ function onSubmit() {
posNo: dataPerson.formData.posNo,
birthDate: dataPerson.formData.birthDate,
};
showLoader();
http
await http
.post(config.API.evaluationExpertise, body)
.then((res) => {
router.push(`/evaluate/detail/expertise/${res.data.result.id}`);
@ -55,12 +55,10 @@ function onSubmit() {
});
}
/**
* fetch รายช งคบบญชาชนต,
*/
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูลรายชื่อ ผู้บังคับบัญชาชั้นต้น */
async function getData() {
isLoading.value = true;
await http
.get(config.API.orgSearchCommander())
.then(async (res) => {
const data = await res.data.result;
@ -74,12 +72,12 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
onMounted(() => {
getData();
onMounted(async () => {
await getData();
});
</script>
@ -103,7 +101,14 @@ onMounted(() => {
</div>
<div class="col-xs-12 col-sm-12 col-md-11 row q-col-gutter-md">
<div class="col-12">
<q-card bordered>
<q-skeleton
v-if="isLoading"
height="230px"
square
style="border-radius: 8px"
/>
<q-card bordered v-else>
<div class="col-12 row q-pa-md q-col-gutter-y-md">
<div class="col-12">
<q-card bordered class="col-12">

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,7 @@ const { showLoader, hideLoader, messageError, formatDatePosition } =
const modal = defineModel<boolean>("modal", { required: true });
const isLoading = ref<boolean>(false);
const cardData = ref<CardDataPos[]>([
{
label: "ระยะเวลาดำรงตำแหน่งในสายงาน",
@ -36,7 +37,7 @@ function onClosePopup() {
}
async function fetchDataPosition() {
showLoader();
isLoading.value = true;
await http
.get(config.API.salaryTenurePosition(""))
.then((res) => {
@ -76,7 +77,7 @@ async function fetchDataPosition() {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -98,7 +99,14 @@ watch(modal, (v) => {
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm q-pb-sm">
<div class="col" v-for="(item, index) in cardData" :key="index">
<q-skeleton v-if="isLoading" width="100%" height="240px" />
<div
v-else
class="col"
v-for="(item, index) in cardData"
:key="index"
>
<q-card bordered class="col-12" style="border: 1px solid #d6dee1">
<div class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md">
{{ item.label }}

View file

@ -1,7 +1,9 @@
<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";
@ -14,25 +16,16 @@ 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,
@ -82,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
@ -127,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;
@ -138,14 +128,16 @@ onMounted(() => {
<d-table
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">
@ -182,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>
@ -227,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>
@ -235,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>

View file

@ -37,6 +37,7 @@ const formData = reactive<FormSpec>({
isHaveProLicense: false, //
isHaveMinPeriodOrHoldPos: false, // ]
});
const isLoading = ref<boolean>(false);
/** function อัปเดทตรวจสอบคุณสมบัติ*/
async function updateValue() {
@ -48,6 +49,7 @@ async function updateValue() {
* @param data ตรวจสอบคณสมบ
*/
async function fetchCheckSpec(data: PersonInformation) {
isLoading.value = true;
formData.isEducationalQft = data.isEducationalQft;
formData.isGovermantServiceHtr = data.isGovermantServiceHtr;
formData.isOperatingExp = data.isOperatingExp;
@ -55,6 +57,7 @@ async function fetchCheckSpec(data: PersonInformation) {
formData.isHaveSpecificQft = data.isHaveSpecificQft;
formData.isHaveProLicense = data.isHaveProLicense;
formData.isHaveMinPeriodOrHoldPos = data.isHaveMinPeriodOrHoldPos;
isLoading.value = false;
}
/**
@ -87,7 +90,8 @@ onMounted(() => {
</script>
<template>
<div class="q-pa-sm">
<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">
<q-item-section avatar>

View file

@ -52,6 +52,7 @@ const formTemplates = ref<any[]>([
fileName: "1-แบบพิจารณาคุณสมบัติบุคคล",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_006",
@ -60,6 +61,7 @@ const formTemplates = ref<any[]>([
fileName: "2-แบบแสดงรายละเอียดการเสนอผลงาน",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_008",
@ -68,6 +70,7 @@ const formTemplates = ref<any[]>([
fileName: "4-แบบประเมินคุณลักษณะบุคคล",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_010",
@ -76,6 +79,7 @@ const formTemplates = ref<any[]>([
fileName: "6-ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11)",
downloadFile: "",
file: null,
isLoading: false,
},
]);
@ -96,6 +100,7 @@ const numOfPages = ref<number>(0);
const page = ref<number>(1);
const pdfSrc = ref<any>();
const profile = ref<any>();
const isLoading = ref<boolean>(false);
/** function ไปหน้าต่อไปของรายงาน */
function nextPage() {
@ -201,8 +206,9 @@ async function uploadfile(uploadUrl: string, file: any) {
* function fecth รายชอผเซนเอกสาร
* @param id evaluate ID
*/
function fetcheSigner(id: string) {
http
async function fetcheSigner(id: string) {
isLoading.value = true;
await http
.get(config.API.evaluationSignerDoc1(id))
.then((res) => {
const data = res.data.result;
@ -220,9 +226,12 @@ function fetcheSigner(id: string) {
formCommand.subject = data.subject;
store.statusUpload = true;
})
.catch(() => {
.catch(async () => {
store.statusUpload = false;
getCommander();
await getCommander();
})
.finally(() => {
isLoading.value = false;
});
}
@ -247,6 +256,11 @@ async function fetchCheckSpec(id: string) {
* @param fileName อไฟล
*/
async function downloadFile(fileName: string) {
const loadingKey = formTemplates.value.findIndex(
(item) => item.fileName === fileName
);
formTemplates.value[loadingKey].isLoading = true;
await http
.get(config.API.loadFileDocument("เล่ม 1", evaluateId.value, fileName))
.then((res) => {
@ -264,6 +278,7 @@ async function downloadFile(fileName: string) {
};
emit("update:form", formCommand, ref);
formTemplates.value[loadingKey].isLoading = false;
});
}
@ -316,29 +331,16 @@ watch(
/**lifecycle Hooks*/
onMounted(async () => {
const user = await tokenParsed();
try {
showLoader();
await Promise.all([
fetcheSigner(evaluateId.value),
fetchCheckSpec(evaluateId.value),
formTemplates.value.forEach((e) => {
downloadFile(e.fileName);
}),
// downloadFile("1-"),
// downloadFile("2-"),
// downloadFile(
// "3- ( )"
// ),
// downloadFile("4-"),
// downloadFile("5- ( 9)"),
// downloadFile("6- ( 11)"),
]);
} catch (error) {
console.log(error);
} finally {
hideLoader();
}
});
</script>
@ -347,7 +349,8 @@ onMounted(async () => {
<div class="col-12 q-pa-sm">
<!-- ผลงาน -->
<div class="col-12">
<q-card bordered class="cardSp1 col-12">
<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">
ผลงาน
</div>
@ -422,7 +425,8 @@ onMounted(async () => {
<!-- เลอกผเซนเอกสาร -->
<div class="col-12">
<q-card bordered class="cardSp1 col-12">
<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">
เลอกผเซนเอกสาร
</div>
@ -573,14 +577,16 @@ onMounted(async () => {
</div>
<!-- v-if="store.statusUpload -->
<div class="row q-col-gutter-sm">
<div class="row q-col-gutter-sm q-mt-sm">
<div
class="col-6"
v-if="store.currentStep === 2"
v-for="(item, index) in formTemplates"
:key="index"
>
<q-card bordered class="cardSp1">
<q-skeleton height="100px" v-if="item.isLoading" />
<q-card bordered class="cardSp1" v-else>
<div
class="text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm col-12 row items-center"
>
@ -662,541 +668,6 @@ onMounted(async () => {
</div>
</q-card>
</div>
<!-- แบบพจารณาคณสมบคคล -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm col-12 row items-center"
>
<div>แบบพจารณาคณสมบคคล</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_005',
'template-1',
'แบบพิจารณาคุณสมบัติบุคคล'
)
"
>
<q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div>
<q-btn
v-if="downloadFile1 != ''"
:href="downloadFile1"
target="_blank"
class="q-ml-sm"
color="blue"
flat
dense
icon="visibility"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<div class="row q-col-gutter-md col-12">
<q-file
ref="fileEvaluation1Ref"
v-model="fileEvaluation1"
:disable="!store.statusUpload"
class="col-xs-12 col-sm-12"
label="อัปโหลดไฟล์"
outlined
dense
lazy-rules
hide-bottom-space
accept=".pdf"
:rules="
downloadFile1 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
:disable="!store.statusUpload"
flat
round
dense
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'1-แบบพิจารณาคุณสมบัติบุคคล',
fileEvaluation1
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</div>
</q-card>
</div> -->
<!-- แบบแสดงรายละเอยดการเสนอผลงาน -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm col-12 row items-center"
>
<div>แบบแสดงรายละเอยดการเสนอผลงาน</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_006',
'template-2',
'แบบแสดงรายละเอียดการเสนอผลงาน'
)
"
>
<q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div>
<q-btn
v-if="downloadFile2 != ''"
:href="downloadFile2"
target="_blank"
class="q-ml-sm"
color="blue"
flat
dense
icon="visibility"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<div class="row q-col-gutter-md col-12">
<q-file
ref="fileEvaluation2Ref"
v-model="fileEvaluation2"
:disable="!store.statusUpload"
class="col-12"
outlined
dense
label="อัปโหลดไฟล์"
lazy-rules
accept=".pdf"
hide-bottom-space
:rules="
downloadFile2 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
:disable="!store.statusUpload"
flat
round
dense
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'2-แบบแสดงรายละเอียดการเสนอผลงาน',
fileEvaluation2
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</div>
</q-card>
</div> -->
<!-- แบบตรวจสอบความถกตองครบถวนของขอมลเพอประกอบการคดเลอกบคคล (เอกสารแบบ ) -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm no-wrap"
>
<div>
แบบตรวจสอบความถกตองครบถวนของขอมลเพอประกอบการคดเลอกบคคล
(เอกสารแบบ .)
</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_007',
'template-3',
'แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)'
)
"
>
<q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div v-if="downloadFile3 != ''">
<q-btn
:href="downloadFile3"
target="_blank"
flat
dense
icon="visibility"
class="q-ml-sm"
color="blue"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<q-file
ref="fileEvaluation3Ref"
v-model="fileEvaluation3"
:disable="!store.statusUpload"
class="col-12"
outlined
dense
lazy-rules
hide-bottom-space
accept=".pdf"
:rules="
downloadFile3 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
label="อัปโหลดไฟล์"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
:disable="!store.statusUpload"
flat
round
dense
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'3-แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)',
fileEvaluation3
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</q-card>
</div> -->
<!-- แบบสรปขอมลของผขอรบการคดเลอก (เอกสารหมายเลข 9) -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm no-wrap"
>
<div class="col-7">
แบบสรปขอมลของผขอรบการคดเลอก (เอกสารหมายเลข 9)
</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_009',
'template-5',
'แบบสรุปข้อมูลของผู้ขอรับการคัดเลือก (เอกสารหมายเลข 9)'
)
"
><q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div>
<q-btn
v-if="downloadFile5 != ''"
:href="downloadFile5"
target="_blank"
flat
dense
icon="visibility"
class="q-ml-sm"
color="blue"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<q-file
ref="fileEvaluation5Ref"
v-model="fileEvaluation5"
:disable="!store.statusUpload"
class="col-12"
outlined
dense
lazy-rules
accept=".pdf"
hide-bottom-space
label="อัปโหลดไฟล์"
:rules="
downloadFile5 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
:disable="!store.statusUpload"
flat
round
dense
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'5-แบบสรุปข้อมูลของผู้ขอรับการคัดเลือก (เอกสารหมายเลข 9)',
fileEvaluation5
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</q-card>
</div> -->
<!-- แบบประเมนคณลกษณะบคคล -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm items-center"
>
<div>แบบประเมนคณลกษณะบคคล</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_008',
'template-4',
'แบบประเมินคุณลักษณะบุคคล'
)
"
>
<q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div>
<q-btn
v-if="downloadFile4 != ''"
:href="downloadFile4"
target="_blank"
flat
dense
icon="visibility"
class="q-ml-sm"
color="blue"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<q-file
ref="fileEvaluation4Ref"
v-model="fileEvaluation4"
:disable="!store.statusUpload"
class="col-12"
outlined
dense
lazy-rules
hide-bottom-space
accept=".pdf"
label="อัปโหลดไฟล์"
:rules="
downloadFile4 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
flat
round
dense
:disable="!store.statusUpload"
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'4-แบบประเมินคุณลักษณะบุคคล',
fileEvaluation4
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</q-card>
</div> -->
<!--ผลงานทจะสงประเม (เอกสารหมายเลข 11) -->
<!-- <div class="col-6" v-if="store.currentStep === 2">
<q-card bordered class="cardSp1">
<div
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm items-center"
>
<div>ผลงานทจะสงประเม (เอกสารหมายเลข 11)</div>
<q-space />
<div>
<q-btn
flat
dense
icon="download"
color="indigo"
@click="
onClickDowloadFile(
'EV1_010',
'template-6',
'ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11)'
)
"
>
<q-tooltip> ดาวนโหลดตนแบบ </q-tooltip></q-btn
>
</div>
<div>
<q-btn
v-if="downloadFile6 != ''"
:href="downloadFile6"
target="_blank"
flat
dense
icon="visibility"
class="q-ml-sm"
color="blue"
>
<q-tooltip> ไฟลเอกสาร </q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="row">
<div class="col-12 q-pa-sm">
<q-file
ref="fileEvaluation6Ref"
v-model="fileEvaluation6"
:disable="!store.statusUpload"
class="col-12"
outlined
hide-bottom-space
dense
lazy-rules
label="อัปโหลดไฟล์"
accept=".pdf"
:rules="
downloadFile6 === ''
? [(val:any) => !!val || 'กรุณาเลือกไฟล์']
: []
"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
<template v-slot:after>
<q-btn
:disable="!store.statusUpload"
flat
round
dense
color="primary"
icon="mdi-upload"
@click="
fetchPathUpload(
'เล่ม 1',
evaluateId,
'6-ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11)',
fileEvaluation6
)
"
><q-tooltip>ปโหลดไฟล</q-tooltip></q-btn
>
</template>
</q-file>
</div>
</div>
</q-card>
</div> -->
</div>
</div>

View file

@ -13,7 +13,7 @@ const $q = useQuasar();
const store = useEvaluateStore();
const mixin = useCounterMixin();
const route = useRoute();
const { showLoader, hideLoader, messageError } = mixin;
const { messageError } = mixin;
/** id ประเมิน*/
const evaluateId = ref<string>(route.params.id.toString());
@ -21,6 +21,7 @@ const evaluateId = ref<string>(route.params.id.toString());
/** emit*/
const emit = defineEmits(["update:file"]);
const isLoading = ref(false);
const selectedItem = ref(1);
const formTemplates = ref([
{
@ -55,8 +56,10 @@ function handleItemClick(itemNumber: number) {
* function เรกยเอกสาร
* @param fileName อเอกสาร
*/
async function fetchDocument(fileName: string) {
showLoader();
async function fetchDocument(fileName: string, forceDownload = false) {
if (forceDownload) {
isLoading.value = true;
}
evaluateId.value &&
(await http
.get(config.API.loadFileDocument("เล่ม 1", evaluateId.value, fileName))
@ -67,7 +70,7 @@ async function fetchDocument(fileName: string) {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
}));
}
@ -95,7 +98,10 @@ async function downloadFile(url: string) {
/** HooK lifecycle*/
onMounted(async () => {
await fetchDocument(formTemplates.value[selectedItem.value - 1].fileName);
await fetchDocument(
formTemplates.value[selectedItem.value - 1].fileName,
true
);
});
</script>
@ -111,7 +117,8 @@ onMounted(async () => {
@click="handleItemClick(index + 1)"
class="cursor-pointer"
>
<q-item-section>{{ item.title }}</q-item-section>
<q-skeleton v-if="isLoading" type="text" width="100%" />
<q-item-section v-else>{{ item.title }}</q-item-section>
</q-item>
</q-list>
</template>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { is, useQuasar } from "quasar";
import axios from "axios";
import http from "@/plugins/http";
@ -23,6 +23,7 @@ const formTemplates = ref<any[]>([
fileName: "1-แบบพิจารณาคุณสมบัติบุคคล (ฉบับแก้ไข)",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_006",
@ -31,6 +32,7 @@ const formTemplates = ref<any[]>([
fileName: "2-แบบแสดงรายละเอียดการเสนอผลงาน (ฉบับแก้ไข)",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_008",
@ -39,6 +41,7 @@ const formTemplates = ref<any[]>([
fileName: "4-แบบประเมินคุณลักษณะบุคคล (ฉบับแก้ไข)",
downloadFile: "",
file: null,
isLoading: false,
},
{
code: "EV1_010",
@ -47,6 +50,7 @@ const formTemplates = ref<any[]>([
fileName: "6-ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11) (ฉบับแก้ไข)",
downloadFile: "",
file: null,
isLoading: false,
},
]);
@ -181,6 +185,10 @@ async function uploadfile(uploadUrl: string, file: any) {
* @param fileName อไฟล
*/
async function downloadFile(fileName: string) {
const loadingKey = formTemplates.value.findIndex(
(item) => item.fileName === fileName
);
formTemplates.value[loadingKey].isLoading = true;
await http
.get(config.API.loadFileDocument("เล่ม 1", evaluateId.value, fileName))
.then((res) => {
@ -190,13 +198,15 @@ async function downloadFile(fileName: string) {
if (index !== -1) {
formTemplates.value[index].downloadFile = res.data.downloadUrl;
}
})
.finally(() => {
formTemplates.value[loadingKey].isLoading = false;
});
}
/**lifecycle Hooks*/
onMounted(async () => {
try {
showLoader();
await Promise.all([
fetcheSigner(evaluateId.value),
fetchCheckSpec(evaluateId.value),
@ -206,8 +216,6 @@ onMounted(async () => {
]);
} catch (error) {
console.log(error);
} finally {
hideLoader();
}
});
</script>
@ -226,7 +234,12 @@ 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
:height="store.currentStep !== 4 ? '50px' : '100px'"
v-if="item.isLoading"
/>
<q-card
v-else
bordered
class="cardSp1"
v-if="

View file

@ -12,7 +12,7 @@ import type { FileObject } from "@/modules/06_evaluate/interface/main";
const $q = useQuasar();
const mixins = useCounterMixin();
const route = useRoute();
const { date2Thai, success, showLoader, hideLoader } = mixins;
const { date2Thai, success, showLoader, hideLoader, messageError } = mixins;
/** id ประเมิน*/
const evaluateId = ref<string>(route.params.id.toString());
@ -20,6 +20,7 @@ const evaluateId = ref<string>(route.params.id.toString());
const dateStartAnnounce = ref<string | null>(date2Thai(new Date()));
const dateEndAnnounce = ref<string | null>(date2Thai(new Date()));
const statusFile = ref<boolean>(false);
const isLoading = ref<boolean>(false);
/** เอกสารประกาศผลการคัดเลือกบุคคล*/
const items = ref<FileObject[]>([
@ -44,22 +45,16 @@ const items = ref<FileObject[]>([
]);
/** fuinction เรียกข้อมูลลิงก์ดาวนฺโหลด*/
function onClickfetchDocument(fileName: string, type: string) {
async function onClickfetchDocument(fileName: string, type: string) {
if (evaluateId.value) {
showLoader();
http
await http
.get(config.API.loadFileDocument("เล่ม 1", evaluateId.value, fileName))
.then((res) => {
const downloadUrl = res.data.downloadUrl;
type === "COPPY" && coppyLink(downloadUrl);
type === "CHECK" && (statusFile.value = true);
})
.catch(() => {})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 1500);
});
.catch(() => {});
}
}
@ -71,9 +66,10 @@ async function coppyLink(link: string) {
}
/** function เรียกข้อมูลวันที่ประกาศ*/
function fetchCheckDate() {
async function fetchCheckDate() {
isLoading.value = true;
evaluateId.value &&
http
(await http
.get(config.API.evaluationCheckDate(evaluateId.value))
.then((res) => {
const data = res.data.result;
@ -82,7 +78,12 @@ function fetchCheckDate() {
endDate.setDate(endDate.getDate() + 30);
dateEndAnnounce.value = date2Thai(endDate);
})
.catch(() => {});
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoading.value = false;
}));
}
/** Hook lifecycle*/
@ -91,10 +92,12 @@ onMounted(async () => {
await onClickfetchDocument("บันทึกแจ้งผลการประกาศคัดเลือก", "CHECK");
});
</script>
`
<template>
<div class="row col-12 q-pa-sm">
<div class="row col-12 q-col-gutter-sm">
<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">
<div class="text-weight-bold">

View file

@ -50,6 +50,10 @@ const formCommand = reactive<FormCommand>({
const modalView = ref<boolean>(false);
const isLoading = ref<boolean>(false); //
const isLoadingFile = ref<boolean>(false);
const isLoadingDate = ref<boolean>(false);
/** function อัปเดท ผลงาน,ผู้เซ็นเอกสาร*/
function updateInput(value: any) {
const ref = {
@ -85,16 +89,18 @@ async function fetchPathUpload(
showLoader();
await http
.post(config.API.loadPathDocument(volume, id), body)
.then((res) => {
.then(async (res) => {
const foundKey: string | undefined = Object.keys(res.data).find(
(key) =>
res.data[key]?.fileName !== undefined &&
res.data[key]?.fileName !== ""
);
foundKey && uploadfile(res.data[foundKey]?.uploadUrl, file);
foundKey && (await uploadfile(res.data[foundKey]?.uploadUrl, file));
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
@ -129,7 +135,7 @@ async function uploadfile(uploadUrl: string, file: any) {
* @param id ประเม
*/
async function fetcheSigner(id: string) {
showLoader();
isLoading.value = true;
await http
.get(config.API.evaluationSignerDoc2(id))
.then((res) => {
@ -148,40 +154,43 @@ async function fetcheSigner(id: string) {
formCommand.author = data.authorDoc2;
formCommand.subject = data.subjectDoc2;
formCommand.assignedPosition = data.assignedPosition;
assignedPosLevel.value = data.assignedPosLevel;
store.statusUpload6 = data.isUpdated;
})
.catch((err) => {
messageError($q, err);
// store.statusUpload6 = false;
// getCommander();
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
const dateEndPrepareDoc2 = ref<string | null>(date2Thai(new Date()));
/** functoin เรียกข้อมูลวันสุดท้ายของการส่งผลงาน*/
async function fetchCheckDate() {
evaluateId.value &&
(await http
.get(config.API.evaluationCheckDate(evaluateId.value))
.then((res) => {
const data = res.data.result;
if (!evaluateId.value) return;
isLoadingDate.value = true;
await http
.get(config.API.evaluationCheckDate(evaluateId.value))
.then((res) => {
const data = res.data.result;
const endDate = new Date(data.dateEndAnnounce);
endDate.setDate(endDate.getDate() + 180);
dateEndPrepareDoc2.value = date2Thai(endDate);
})
.catch((err) => {}));
const endDate = new Date(data.dateEndAnnounce);
endDate.setDate(endDate.getDate() + 180);
dateEndPrepareDoc2.value = date2Thai(endDate);
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoadingDate.value = false;
});
}
const downloadUrl = ref<string>("");
/** function เช็คไฟล์อัปโหลด*/
async function checkDoc() {
isLoadingFile.value = true;
await http
.get(
config.API.loadFileDocument("เล่ม 2", evaluateId.value, "1-เอกสารเล่ม 2")
@ -195,26 +204,10 @@ async function checkDoc() {
};
emit("update:form", formCommand, ref);
isLoadingFile.value = false;
});
}
// function getCommander() {
// http
// .get(config.API.searchCommander)
// .then((res) => {
// const data = res.data.result;
// formCommand.commanderFullname = data.commanderFullname;
// formCommand.commanderPosition = data.commanderPosition;
// formCommand.commanderAboveFullname = data.commanderAboveFullname;
// formCommand.commanderAbovePosition = data.commanderAbovePosition;
// formCommand.commanderOrg = data.commanderOrg;
// formCommand.commanderAboveOrg = data.commanderAboveOrg;
// })
// .catch((e) => {
// messageError($q, e);
// });
// }
function onAddSubject() {
formCommand.subject.push("");
}
@ -256,9 +249,10 @@ onMounted(async () => {
<template>
<div class="row col-12 q-pa-sm">
<div class="row q-col-gutter-sm">
<div 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">
<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" />
นสดทายของการสงผลงานคอวนท {{ dateEndPrepareDoc2 }}
@ -268,7 +262,14 @@ onMounted(async () => {
<!-- ผลงาน -->
<div class="col-12">
<q-card bordered class="shadow-0" style="border: 1px solid #d6dee1">
<q-skeleton v-if="isLoading" height="200px" width="100%" />
<q-card
v-else
bordered
class="shadow-0"
style="border: 1px solid #d6dee1"
>
<div class="text-weight-medium bg-grey-1 q-py-sm q-px-md">ผลงาน</div>
<div class="col-12"><q-separator /></div>
<div class="col-12 q-pa-sm">
@ -372,7 +373,13 @@ onMounted(async () => {
<!-- เลอกผเซนเอกสาร -->
<div class="col-12">
<q-card bordered class="shadow-0" style="border: 1px solid #d6dee1">
<q-skeleton v-if="isLoading" height="200px" width="100%" />
<q-card
v-else
bordered
class="shadow-0"
style="border: 1px solid #d6dee1"
>
<div class="text-weight-medium bg-grey-1 q-py-sm q-px-md">
เลอกผเซนเอกสาร
</div>
@ -541,7 +548,13 @@ onMounted(async () => {
<!-- ปไฟล -->
<div class="col-12" v-if="store.currentStep === 6">
<q-card bordered class="shadow-0" style="border: 1px solid #d6dee1">
<q-skeleton height="100px" v-if="isLoadingFile" />
<q-card
v-else
bordered
class="shadow-0"
style="border: 1px solid #d6dee1"
>
<div class="col-12 row bg-grey-1">
<div class="text-weight-medium q-py-sm q-px-md">เอกสารเล 2</div>
<q-space />

View file

@ -13,7 +13,7 @@ import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const mixin = useCounterMixin();
const route = useRoute();
const { showLoader, hideLoader, messageError } = mixin;
const { messageError } = mixin;
/** emit*/
const emit = defineEmits(["update:file"]);
@ -22,28 +22,25 @@ const emit = defineEmits(["update:file"]);
const evaluateId = ref<string>(route.params.id.toString());
const selectedItem = ref(1);
const isLoading = ref(false);
/** function เรีกยเอกสาร*/
async function fetchDocument() {
showLoader();
evaluateId.value &&
(await http
.get(
config.API.loadFileDocument(
"เล่ม 2",
evaluateId.value,
"1-เอกสารเล่ม 2"
)
)
.then(async (res) => {
await downloadFile(res.data.downloadUrl);
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
}));
if (!evaluateId.value) return;
isLoading.value = true;
await http
.get(
config.API.loadFileDocument("เล่ม 2", evaluateId.value, "1-เอกสารเล่ม 2")
)
.then(async (res) => {
await downloadFile(res.data.downloadUrl);
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoading.value = false;
});
}
/**
@ -84,7 +81,9 @@ onMounted(async () => {
active-class="text-primary"
class="cursor-pointer"
>
<q-item-section>เอกสารเล 2</q-item-section>
<q-skeleton v-if="isLoading" type="text" width="100%" />
<q-item-section v-else>เอกสารเล่ม 2</q-item-section>
</q-item>
</q-list>
</template>

View file

@ -107,9 +107,11 @@ async function uploadfile(uploadUrl: string, file: any) {
}
const downloadUrl = ref<string>("");
const isLoadingFile = ref<boolean>(false);
/** function เช็คไฟล์อัปโหลด*/
function checkDoc() {
http
async function checkDoc() {
isLoadingFile.value = true;
await http
.get(
config.API.loadFileDocument(
"เล่ม 2",
@ -119,6 +121,9 @@ function checkDoc() {
)
.then((res: any) => {
downloadUrl.value = res.data.downloadUrl;
})
.finally(() => {
isLoadingFile.value = false;
});
}
@ -148,12 +153,9 @@ async function fetcheSigner(id: string) {
/** lifecycleHook*/
onMounted(async () => {
try {
showLoader();
await Promise.all([checkDoc(), fetcheSigner(evaluateId.value)]);
} catch (error) {
console.log(error);
} finally {
hideLoader();
}
});
</script>
@ -178,7 +180,11 @@ onMounted(async () => {
(store.currentStep !== 8 && downloadUrl) || store.currentStep == 8
"
>
<q-card class="shadow-0" bordered>
<q-skeleton
:height="store.currentStep !== 8 ? '50px' : '100px'"
v-if="isLoadingFile"
/>
<q-card v-else class="shadow-0" bordered>
<div class="row col-12 bg-grey-1 q-px-sm q-py-xs items-center">
<div class="text-weight-medium">เอกสารเล 2 (ฉบบแกไข)</div>
<q-space />

View file

@ -13,7 +13,9 @@ import HeaderDialog from "@/components/DialogHeader.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);
const evaluateId = computed(() => {
const id = route.params.id ? route.params.id.toString() : "";
@ -85,7 +87,7 @@ async function fetchListHistory(id: string) {
minute: "2-digit",
second: "2-digit",
};
showLoader();
isLoading.value = true;
await http
.get(config.API.evaluationHistory(id))
.then((res) => {
@ -104,7 +106,7 @@ async function fetchListHistory(id: string) {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -124,7 +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">
<q-table
<d-table
ref="table"
flat
bordered
@ -133,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">
@ -161,7 +165,7 @@ watch(
</q-td>
</q-tr>
</template>
</q-table>
</d-table>
</div>
</div>
</q-card-section>
@ -169,31 +173,4 @@ watch(
</q-dialog>
</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>

View file

@ -8,6 +8,10 @@ const props = defineProps({
type: Array as () => any[],
require: true,
},
isLoading: {
type: Boolean,
default: false,
},
});
</script>
@ -24,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">
@ -46,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>

View file

@ -29,8 +29,7 @@ const storeEva = useEvaluateStore();
const storeData = useDataStore();
const $q = useQuasar();
const route = useRoute();
const { showLoader, hideLoader, messageError, date2Thai, findOrgNameHtml } =
mixin;
const { messageError, date2Thai, findOrgNameHtml } = mixin;
const {
columnsCertificates,
columnSalaries,
@ -76,8 +75,19 @@ const formDetail = reactive<any>({
honor: [],
});
const isLoading = reactive({
loadDetail: false,
loadEducation: false,
loadCertificate: false,
loadSalary: false,
loadTraining: false,
loadAssessment: false,
loadExperience: false,
});
/** function เรียกข้อมูลตรวจสอบคุณสมบัติ*/
async function fetchDetail() {
isLoading.loadDetail = true;
try {
if (!storeData.dataprofilePosition) {
const res = await http.get(config.API.profilePosition());
@ -87,6 +97,8 @@ async function fetchDetail() {
}
} catch (error) {
messageError($q, error);
} finally {
isLoading.loadDetail = false;
}
}
@ -109,58 +121,113 @@ async function updateFormDetail(data: DataProfile) {
formDetail.posExecutive = data.posExecutiveName;
formDetail.positionArea = data.positionArea;
await fetchDataAllDetail();
emit("update:formDeital", formDetail);
}
async function fetchDataAllDetail() {
//
http.get(config.API.dataUserEducations).then((res) => {
formDetail.educations = res.data.result;
});
isLoading.loadEducation = true;
http
.get(config.API.dataUserEducations)
.then((res) => {
formDetail.educations = res.data.result;
})
.catch((e) => {
messageError($q, e);
})
.then(() => {
isLoading.loadEducation = false;
});
//
http.get(config.API.dataUserCertificate("certificate")).then((res) => {
formDetail.certificates = res.data.result.map((e: CertificatesForm) => ({
certificateNo: e.certificateNo,
certificateType: e.certificateType,
expireDate: e.expireDate,
issueDate: e.issueDate,
issuer: e.issuer,
}));
});
isLoading.loadCertificate = true;
http
.get(config.API.dataUserCertificate("certificate"))
.then((res) => {
formDetail.certificates = res.data.result.map((e: CertificatesForm) => ({
certificateNo: e.certificateNo,
certificateType: e.certificateType,
expireDate: e.expireDate,
issueDate: e.issueDate,
issuer: e.issuer,
}));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadCertificate = false;
});
//
http.get(config.API.dataUserSalaryPosition).then((res) => {
formDetail.salaries = res.data.result;
});
isLoading.loadSalary = true;
http
.get(config.API.dataUserSalaryPosition)
.then((res) => {
formDetail.salaries = res.data.result;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadSalary = false;
});
//
http.get(config.API.dataUserCertificate("training")).then((res) => {
formDetail.trainings = res.data.result.map((e: any) => ({
dateOrder: e.dateOrder,
department: e.department,
duration: e.duration,
endDate: e.endDate,
name: e.name,
numberOrder: e.numberOrder,
place: e.place,
startDate: e.startDate,
topic: e.topic,
yearly: e.yearly,
}));
});
isLoading.loadTraining = true;
http
.get(config.API.dataUserCertificate("training"))
.then((res) => {
formDetail.trainings = res.data.result.map((e: any) => ({
dateOrder: e.dateOrder,
department: e.department,
duration: e.duration,
endDate: e.endDate,
name: e.name,
numberOrder: e.numberOrder,
place: e.place,
startDate: e.startDate,
topic: e.topic,
yearly: e.yearly,
}));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadTraining = false;
});
http.get(config.API.dataUserPerformance).then((res) => {
formDetail.assessments = res.data.result.map((e: any) => ({
...e,
isAdd: false,
}));
});
//
isLoading.loadExperience = true;
http
.get(config.API.dataUserPerformance)
.then((res) => {
formDetail.assessments = res.data.result.map((e: any) => ({
...e,
isAdd: false,
}));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadExperience = false;
});
http.get(config.API.dataUserPortfolio).then((res) => {
formDetail.experience = res.data.result;
});
//
isLoading.loadExperience = true;
http
.get(config.API.dataUserPortfolio)
.then((res) => {
formDetail.experience = res.data.result;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadExperience = false;
});
}
/**
@ -168,40 +235,52 @@ async function fetchDataAllDetail() {
* @param id ประเม
*/
async function fetchCheckSpec(data: any) {
formDetail.userId = data.id;
formDetail.citizenId = data.citizenId;
formDetail.prefix = data.prefix;
formDetail.fullName = data.fullName;
formDetail.position = data.position;
formDetail.oc = data.oc;
formDetail.salary = data.salary ? formattedNumber(data.salary) : "";
formDetail.positionLevel = data.positionLevel;
formDetail.posNo = data.posNo;
formDetail.birthDate = data.birthDate;
formDetail.educations = data.educations;
formDetail.certificates = data.certificates.map((e: CertificatesForm) => ({
certificateNo: e.certificateNo,
certificateType: e.certificateType,
expireDate: date2Thai(e.expireDate),
issueDate: date2Thai(e.issueDate),
issuer: e.issuer,
}));
formDetail.salaries = data.salaries;
formDetail.trainings = data.trainings.map((e: any) => ({
dateOrder: date2Thai(e.dateOrder),
department: e.department,
duration: e.duration,
endDate: date2Thai(e.endDate),
name: e.name,
numberOrder: e.numberOrder,
place: e.place,
startDate: date2Thai(e.startDate),
topic: e.topic,
yearly: e.yearly,
}));
formDetail.assessments = data.performances;
formDetail.experience = data.portfolios;
isLoading.loadEducation = true;
isLoading.loadCertificate = true;
isLoading.loadSalary = true;
isLoading.loadTraining = true;
isLoading.loadExperience = true;
try {
formDetail.userId = data.id;
formDetail.citizenId = data.citizenId;
formDetail.prefix = data.prefix;
formDetail.fullName = data.fullName;
formDetail.position = data.position;
formDetail.oc = data.oc;
formDetail.salary = data.salary ? formattedNumber(data.salary) : "";
formDetail.positionLevel = data.positionLevel;
formDetail.posNo = data.posNo;
formDetail.birthDate = data.birthDate;
formDetail.educations = data.educations;
formDetail.certificates = data.certificates.map((e: CertificatesForm) => ({
certificateNo: e.certificateNo,
certificateType: e.certificateType,
expireDate: date2Thai(e.expireDate),
issueDate: date2Thai(e.issueDate),
issuer: e.issuer,
}));
formDetail.salaries = data.salaries;
formDetail.trainings = data.trainings.map((e: any) => ({
dateOrder: date2Thai(e.dateOrder),
department: e.department,
duration: e.duration,
endDate: date2Thai(e.endDate),
name: e.name,
numberOrder: e.numberOrder,
place: e.place,
startDate: date2Thai(e.startDate),
topic: e.topic,
yearly: e.yearly,
}));
formDetail.assessments = data.performances;
formDetail.experience = data.portfolios;
} finally {
isLoading.loadEducation = false;
isLoading.loadCertificate = false;
isLoading.loadSalary = false;
isLoading.loadTraining = false;
isLoading.loadExperience = false;
}
}
/**
@ -218,6 +297,7 @@ function formattedNumber(x: number) {
/** get data */
function getData() {
isLoading.loadDetail = true;
http
.get(config.API.dataUserGovernment)
.then(async (res) => {
@ -229,6 +309,9 @@ function getData() {
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.loadDetail = false;
});
}
@ -298,7 +381,6 @@ function onDeletePerformance(index: number) {
onMounted(async () => {
try {
showLoader();
const promises = [];
if (route.name === "evaluate-add") {
@ -315,7 +397,6 @@ onMounted(async () => {
} catch (error) {
console.log(error);
} finally {
hideLoader();
}
});
</script>
@ -327,7 +408,10 @@ onMounted(async () => {
:style="$q.screen.lt.sm ? '' : 'height: 60vh; overflow: scroll;'"
>
<div class="row col-12">
<q-card class="col-12 cardSp1" bordered>
<div class="col-12" v-if="isLoading.loadDetail">
<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">
<span class="q-ml-lg q-my-sm">อมลสวนต</span>
</div>
@ -430,7 +514,10 @@ onMounted(async () => {
</div>
</q-card>
<q-card class="col-12 cardSp1" bordered>
<div class="col-12" v-if="isLoading.loadEducation">
<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">
<span class="q-ml-lg q-my-sm">ประวการศกษา </span>
</div>
@ -571,6 +658,7 @@ onMounted(async () => {
class="col-12"
:columns="columnsCertificates"
:row="formDetail.certificates"
:is-loading="isLoading.loadCertificate"
/>
</q-card>
@ -579,7 +667,7 @@ onMounted(async () => {
<span class="q-ml-lg q-my-sm">ประวการรบราชการ</span>
</div>
<div class="col-12"><q-separator /></div>
<div class="col-10">
<div class="col-10 q-pa-sm">
<d-table
ref="table"
row-key="id"
@ -590,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">
@ -637,6 +727,7 @@ onMounted(async () => {
class="col-12"
:columns="columnTraining"
:row="formDetail.trainings"
:is-loading="isLoading.loadTraining"
/>
</q-card>
@ -649,6 +740,7 @@ onMounted(async () => {
class="col-12"
:columns="columnExperience"
:row="formDetail.experience"
:is-loading="isLoading.loadExperience"
/>
</q-card>
@ -681,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">

View file

@ -14,6 +14,7 @@ import TableListEvaluate from "@/modules/06_evaluate/components/TableListEvaluat
import DialogMain from "@/modules/06_evaluate/components/DialogMain.vue"; // popup
/** import 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";
@ -23,9 +24,10 @@ const mixin = useCounterMixin();
const store = useEvaluateStore();
const dataStore = useDataStore();
const router = useRouter();
const { showLoader, hideLoader, messageError } = mixin;
const { messageError } = mixin;
/** ตัวแปร*/
const isLoading = ref<boolean>(false);
const modal = ref<boolean>(false);
const menu = ref<ListMenu>();
const listMenu = ref<ListMenu[]>([
@ -49,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,
});
/**
@ -73,7 +74,8 @@ function openExpert() {
/** function เรียกรายการประเมิน*/
async function fetchEvaluteList() {
showLoader();
isLoading.value = true;
const body = {
page: pagination.value.page,
pageSize: pagination.value.rowsPerPage,
@ -83,17 +85,15 @@ 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);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -191,13 +191,6 @@ function getSearch() {
fetchEvaluteList();
}
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/** hook lifecycle*/
onMounted(async () => {
await fetchEvaluteList();
@ -323,9 +316,8 @@ onMounted(async () => {
<div class="col-12">
<TableListEvaluate
:fetchData="fetchEvaluteList"
v-model:total="total"
v-model:total-list="totalList"
v-model:pagination="pagination"
v-model:isLoading="isLoading"
/>
</div>
</q-card>

View file

@ -21,6 +21,7 @@ const $q = useQuasar();
const mixin = useCounterMixin();
const storeData = useDataStore();
const isLoad = ref<boolean>(false)
const { findOrgName, success, messageError, showLoader, hideLoader } = mixin;
const formProfile = reactive<FormProfile>({
@ -34,15 +35,18 @@ const formProfile = reactive<FormProfile>({
/** ดึงข้อมูลจาก keycloak*/
async function getProFile() {
try {
showLoader();
isLoad.value = true
if (!storeData.dataprofilePosition) {
const res = await http.get(config.API.profilePosition());
await updateFormProfile(res.data.result);
isLoad.value = false
} else {
await updateFormProfile(storeData.dataprofilePosition);
isLoad.value = false
}
} catch (error) {
messageError($q, error);
isLoad.value = false
} finally {
hideLoader();
}
@ -113,7 +117,7 @@ onMounted(() => {
/>
เพมอทธรณ/องทกข
</div>
<Form :on-submit="onSubmit" :form-profile="formProfile" />
<Form :on-submit="onSubmit" :form-profile="formProfile" v-model:isLoad="isLoad"/>
</div>
</div>
</template>

View file

@ -22,6 +22,7 @@ const route = useRoute();
const mixin = useCounterMixin();
const { messageError, showLoader, hideLoader } = mixin;
const isLoad = ref<boolean>(false);
const id = ref<string>(route.params.id as string);
const historyStatusOb = reactive<HistoryStatusType>({
status: "",
@ -53,7 +54,7 @@ const data = reactive<EditDataList>({
/** ดึงข้อมูล */
function getData() {
showLoader();
isLoad.value = true;
http
.get(config.API.appealByID(id.value))
.then((res) => {
@ -73,13 +74,13 @@ function getData() {
data.disciplineComplaint_Appeal_Docs =
dataList.disciplineComplaint_Appeal_Docs;
data.historyStatus = dataList.historyStatus;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/** /
@ -122,7 +123,7 @@ onMounted(() => {
/>
แกไขอทธรณ/องทกข
</div>
<Form :data="data" :get-report="getReport" />
<Form :data="data" :get-report="getReport" v-model:is-load="isLoad"/>
</div>
</div>
</template>

View file

@ -17,6 +17,7 @@ const mixin = useCounterMixin();
const { dialogConfirm } = mixin;
const dataStore = useAppealComplainStore();
const isLoad = defineModel<boolean>("isLoad", { required: true });
const printForm = ref<string>("");
const isReadOnly = ref<boolean>(false);
const historyStatusOb = reactive<HistoryStatusType>({
@ -237,6 +238,7 @@ watch(
<div class="row q-col-gutter-sm">
<div class="col-xs-12 col-md-3">
<q-select
v-if="!isLoad"
:class="inputEdit(isReadOnly)"
:readonly="isReadOnly"
ref="typeRef"
@ -253,9 +255,11 @@ watch(
lazy-rules
hide-bottom-space
/>
<q-skeleton v-else type="QSelect" height="40px" />
</div>
<div class="col-xs-12 col-md-3">
<q-input
v-if="!isLoad"
:class="inputEdit(isReadOnly)"
:readonly="isReadOnly"
ref="titleRef"
@ -268,11 +272,13 @@ watch(
label="เรื่องอุทธรณ์/ร้องทุกข์"
hide-bottom-space
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<div class="row">
<div class="col-12">
<q-input
v-if="!isLoad"
:class="inputEdit(isReadOnly)"
:readonly="isReadOnly"
ref="descriptionRef"
@ -287,11 +293,13 @@ watch(
rows="5"
hide-bottom-space
/>
<q-skeleton v-else type="QInput" height="120px" />
</div>
</div>
<div class="row" v-if="!isReadOnly">
<div class="col-12">
<q-file
v-if="!isLoad"
ref="fileRef"
v-model="formData.files"
label="อัปโหลดเอกสารหลักฐาน"
@ -301,6 +309,7 @@ watch(
hide-bottom-space
bg-color="white"
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-card bordered class="col-12 row" v-if="isReadOnly">
@ -350,11 +359,11 @@ watch(
</q-card>
</div>
</div>
<q-separator v-if="!isReadOnly" />
<q-separator v-if="!isReadOnly && !isLoad" />
<q-card-actions
align="right"
class="bg-white text-teal"
v-if="!isReadOnly"
v-if="!isReadOnly && !isLoad"
>
<q-btn id="onSubmit" type="submit" label="บันทึก" color="secondary"
><q-tooltip>นท</q-tooltip></q-btn

View file

@ -10,6 +10,7 @@ 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";
@ -17,7 +18,7 @@ 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[]>([
@ -25,25 +26,19 @@ const type = ref<DataOption[]>([
...dataStore.typeOptions,
]);
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
const isload = ref<boolean>(false);
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",
@ -56,7 +51,6 @@ const visibleColumns = ref<string[]>([
"lastUpdatedAt",
"status",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -154,7 +148,7 @@ const columns = ref<QTableProps["columns"]>([
//
async function getData() {
showLoader();
isload.value = true;
await http
.get(
config.API.appealMainList(
@ -166,19 +160,16 @@ async function getData() {
filterKeyword.value
)
)
.then((res) => {
totalList.value = Math.ceil(
res.data.result.total / pagination.value.rowsPerPage
);
total.value = res.data.result.total;
let data = res.data.result.data;
dataStore.fetchAppealComplain(data);
.then(async (res) => {
const result = res.data.result;
pagination.value.rowsNumber = result.total;
dataStore.fetchAppealComplain(result.data);
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isload.value = false;
});
}
@ -211,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();
}
/**
* เรยกฟงกนทงหมดตอนเรยกใชไฟล
@ -238,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">
@ -378,29 +369,14 @@ onMounted(async () => {
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
@ -419,14 +395,10 @@ 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'">
{{
(pagination.page - 1) * pagination.rowsPerPage +
props.rowIndex +
1
}}
{{ props.rowIndex + 1 }}
</div>
<div v-else>
@ -439,7 +411,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>
@ -463,49 +435,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>

View file

@ -1,15 +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";
const store = useKpiDataStore();
const router = useRouter();
const isLoad = defineModel<boolean>("isLoad", { required: true });
const visibleColumns = defineModel<string[]>("visibleColumns", {
required: true,
});
@ -19,24 +21,48 @@ 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>
@ -50,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">
@ -105,20 +131,6 @@ 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>
</div>
</template>

View file

@ -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,6 +9,7 @@ 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";
@ -33,24 +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(
@ -104,6 +105,31 @@ 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>
@ -120,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" />
@ -187,10 +214,7 @@ async function onClickApprove(type: string = "") {
</q-card-section>
<q-separator />
<q-list @click="redirectViewDetail(props.row.id)">
<q-item
v-for="col in props.cols"
:key="col.name"
>
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section>
<q-item-label caption>{{ col.label }}</q-item-label>
@ -210,20 +234,6 @@ 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>
</div>

View file

@ -37,6 +37,10 @@ const store = useKpiDataStore();
const evaluationId = ref<string>(route.params.id.toString());
const isLoad01 = ref<boolean>(false);
const isLoad02 = ref<boolean>(false);
const isLoad03 = ref<boolean>(false);
const rows_01 = ref<EvaluationIndicatorType[]>();
const rows_02 = ref<EvaluationIndicatorType[]>();
const rows_03 = ref<EvaluationIndicatorType[]>();
@ -53,6 +57,7 @@ const resultRole = ref<number>(0);
const resultAssigned = ref<number>(0);
function fetchListPlanned() {
isLoad01.value = true;
http
.get(config.API.kpiAchievement("planned") + `?id=${evaluationId.value}`)
.then((res) => {
@ -62,6 +67,7 @@ function fetchListPlanned() {
evaluationResults: (e.point / 5) * e.weight,
}));
rows_01.value = newRow;
isLoad01.value = false;
if (newRow.length > 0) {
resultPlanned.value = newRow.reduce(
@ -89,6 +95,7 @@ function fetchListPlanned() {
}
function fetchListRole() {
isLoad02.value = true;
http
.get(config.API.kpiAchievement("role") + `?id=${evaluationId.value}`)
.then((res) => {
@ -98,7 +105,7 @@ function fetchListRole() {
evaluationResults: (e.point / 5) * e.weight,
}));
rows_02.value = newRow;
isLoad02.value = false;
if (newRow.length > 0) {
resultRole.value = newRow.reduce(
(sum: number, e: any) => sum + e.evaluationResults,
@ -119,6 +126,7 @@ function fetchListRole() {
}
function fetchAssigned() {
isLoad03.value = true;
http
.get(config.API.kpiAchievement("special") + `?id=${evaluationId.value}`)
.then((res) => {
@ -129,7 +137,7 @@ function fetchAssigned() {
}));
rows_03.value = newRow;
isLoad03.value = false;
if (newRow.length > 0) {
resultAssigned.value = newRow.reduce(
(sum: number, e: any) => sum + e.evaluationResults,
@ -262,6 +270,7 @@ const groupNo = computed(() => {
});
onMounted(() => {
store.indicatorWeightTotal = 0
getCriteria();
fetchListPlanned();
fetchListRole();
@ -345,6 +354,7 @@ onMounted(() => {
<div v-if="groupNo == 1">
<Work
v-model:data="rows_01"
v-model:isLoad="isLoad01"
:title="`มิติที่ 1 ภารกิจตามนโยบายและยุทธศาสตร์ของกรุงเทพมหานคร`"
:page="1"
:fetchList="fetchListPlanned"
@ -391,6 +401,7 @@ onMounted(() => {
<Work
v-model:data="rows_03"
v-model:isLoad="isLoad03"
:title="`มิติที่ 2 วาระเร่งด่วนที่ได้รับมอบหมายพิเศษ (ถ้ามี)`"
:page="3"
:fetchList="fetchAssigned"
@ -437,12 +448,16 @@ onMounted(() => {
คะแนน)</span
>
<div class="text-primary q-pl-md">
{{
(
store.excusiveIndicator1ScoreVal +
store.excusiveIndicator2ScoreVal
).toFixed(2)
}}
<div v-if="!isLoad01">
{{
(
store.excusiveIndicator1ScoreVal +
store.excusiveIndicator2ScoreVal
).toFixed(2)
}}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
</div>
@ -452,6 +467,7 @@ onMounted(() => {
<div v-else>
<Work
v-model:data="rows_01"
v-model:isLoad="isLoad01"
:title="`1. งานตามแผนปฏิบัติราชการประจำปี`"
:page="1"
:fetchList="fetchListPlanned"
@ -459,6 +475,7 @@ onMounted(() => {
/>
<Work
v-model:data="rows_02"
v-model:isLoad="isLoad02"
:title="`2. งานตามหน้าที่ความรับผิดชอบหลัก`"
:page="2"
:fetchList="fetchListRole"
@ -466,6 +483,7 @@ onMounted(() => {
/>
<Work
v-model:data="rows_03"
v-model:isLoad="isLoad03"
:title="`3. งานอื่น ๆ ที่ได้รับมอบหมาย`"
:page="3"
:fetchList="fetchAssigned"
@ -517,7 +535,10 @@ onMounted(() => {
คะแนน)</span
>
<div class="text-primary q-pl-md">
{{ store.indicatorScoreVal.toFixed(2) }}
<div v-if="!isLoad01">
{{ store.indicatorScoreVal.toFixed(2) }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
</div>

View file

@ -192,7 +192,9 @@ function userOpen() {
});
}
const isLoad = ref<boolean>(false);
function getData() {
isLoad.value = true;
http
.get(config.API.kpiSendToGet(id.value))
.then((res) => {
@ -220,9 +222,11 @@ function getData() {
sumWeight.value = data.weightPoint1 + data.weightPoint2;
sumResult.value = data.summaryPoint;
result.value = data.evaluationResults;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {});
}
@ -306,22 +310,47 @@ onMounted(() => {
<tbody>
<tr>
<td class="text-left">องคประกอบท 1 ผลสมฤทธของงาน</td>
<td class="text-left">{{ weight1 }}</td>
<td class="text-left">{{ result1 }}</td>
<td class="text-left">
<div v-if="!isLoad">
{{ weight1 }}
</div>
<q-skeleton v-else type="text" />
</td>
<td class="text-left">
<div v-if="!isLoad">{{ result1 }}</div>
<q-skeleton v-else type="text" />
</td>
</tr>
<tr>
<td class="text-left">
องคประกอบท 2 พฤตกรรมการปฎราชการ (สมรรถนะ)
</td>
<td class="text-left">{{ weight2 }}</td>
<td class="text-left">{{ result2 }}</td>
<td class="text-left">
<div v-if="!isLoad">{{ weight2 }}</div>
<q-skeleton v-else type="text" />
</td>
<td class="text-left">
<div v-if="!isLoad">{{ result2 }}</div>
<q-skeleton v-else type="text" />
</td>
</tr>
<tr>
<td class="text-right text-bold" style="font-size: 16px">
รวม
</td>
<td class="text-left">{{ sumWeight }}</td>
<td class="text-left">{{ sumResult }}</td>
<td class="text-left">
<div v-if="!isLoad">{{ sumWeight }}</div>
<q-skeleton v-else type="text" />
</td>
<td class="text-left">
<div v-if="!isLoad">{{ sumResult }}</div>
<q-skeleton v-else type="text" />
</td>
</tr>
</tbody>
</q-markup-table>
@ -332,7 +361,7 @@ onMounted(() => {
</div>
</div>
<div class="col-12 no-pointer">
<div class="column">
<div class="column" v-if="!isLoad">
<q-radio
v-model="result"
checked-icon="task_alt"
@ -369,6 +398,12 @@ onMounted(() => {
label="ต้องปรับปรุง (คะแนนต่ำกว่าร้อยละ 60.00)"
/>
</div>
<q-item v-else dense v-for="item in 5" style="max-width: 300px;">
<q-item-section class="q-pa-none">
<q-skeleton type="text" />
</q-item-section>
</q-item>
</div>
<div class="col-12">
<div class="text-weight-bold text-body2">
@ -378,6 +413,7 @@ onMounted(() => {
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="title"
outlined
lazy-rules
@ -390,9 +426,11 @@ onMounted(() => {
"
:rules="[(val:string) => !!val || `${'กรุณากรอกชื่อเรื่อง/เนื้อหา/หัวข้อการพัฒนา'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="developmentMethod"
outlined
lazy-rules
@ -405,9 +443,11 @@ onMounted(() => {
"
:rules="[(val:string) => !!val || `${'กรุณากรอกวิธีการพัฒนา'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="developmentPeriod"
outlined
hide-bottom-space
@ -420,6 +460,7 @@ onMounted(() => {
"
:rules="[(val:string) => !!val || `${'กรุณากรอกช่วงเวลาการพัฒนา'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<div class="text-weight-bold text-body2">
@ -428,6 +469,7 @@ onMounted(() => {
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="evaluatorComment"
outlined
lazy-rules
@ -440,6 +482,7 @@ onMounted(() => {
"
:rules="[(val:string) => !!val || `${'กรุณากรอกความเห็นของ'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
</div>
</q-card-section>
@ -519,6 +562,7 @@ onMounted(() => {
<div class="col-12">
<q-input
v-if="!isLoad"
lazy-rules
v-model="superiorComment"
outlined
@ -538,6 +582,7 @@ onMounted(() => {
ref="superiorCommentRef"
:rules="[(val:string) => superiorCommentCheck !== 'false'||!!val || `${'กรุณากรอกความเห็น'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
</div>
</q-card-section>
@ -621,6 +666,7 @@ onMounted(() => {
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
lazy-rules
ref="additionalSuperiorCommentRef"
v-model="additionalSuperiorComment"
@ -641,6 +687,7 @@ onMounted(() => {
"
:rules="[(val:string) => additionalSuperiorCheck !== 'false'||!!val || `${'กรุณากรอกความเห็น'}`,]"
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
</div>
</q-card-section>

View file

@ -32,18 +32,20 @@ const isReadonly = ref<boolean>(
const documentFile = ref<any>(null);
const fileList = ref<ArrayFileList[]>([]);
const isLoad = ref<boolean>(false);
async function getData() {
showLoader();
isLoad.value = true;
await http
.get(config.API.file("ไฟล์เอกสาร", "KPI", id.value))
.then((res) => {
fileList.value = res.data;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
@ -190,7 +192,11 @@ onMounted(() => {
<!-- <div class="col-1 self-center" v-if="formData.documentFile"></div> -->
</div>
<div v-if="fileList.length > 0" class="col-xs-12 row">
<div v-if="isLoad" class="col-12">
<q-skeleton />
</div>
<div v-else-if="fileList.length > 0" class="col-xs-12 row">
<q-list class="full-width rounded-borders" bordered separator>
<q-item
clickable

View file

@ -36,6 +36,8 @@ const search = ref<string>("");
const listCheckID = ref<string | null>(null);
const listTarget = ref<any>([]);
const isLoad = ref<boolean>(false);
const isLoadList = ref<boolean>(false);
const formFilter = reactive<any>({
isAll: false,
keyword: "",
@ -91,20 +93,20 @@ function fetchListPlan() {
: store.dataProfile.nodeDnaId;
formFilter.node = formFilter.isAll ? 0 : store.dataProfile.node;
formFilter.year = formFilter?.year ? formFilter.year.toString() : "";
showLoader();
isLoadList.value = true;
http
.post(config.API.kpiPlan + `/search`, formFilter)
.then((res) => {
listTarget.value = res.data.result.data;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
totalList.value = res.data.result.total;
isLoadList.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoadList.value = false;
});
}
@ -113,7 +115,7 @@ function fetchListPlan() {
* @param id id
*/
function fetchListPlanByid(id: string) {
showLoader();
isLoad.value = true;
http
.get(config.API.kpiAchievement("planned") + `/${id}`)
.then((res) => {
@ -138,12 +140,13 @@ function fetchListPlanByid(id: string) {
formDetail.endDate = data.endDate;
listCheckID.value = data.kpiPlanId;
isLoad.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
@ -154,24 +157,25 @@ function fetchListRole() {
formFilter.node = formFilter.isAll ? 0 : store.dataProfile.node;
formFilter.year = formFilter?.year ? formFilter.year.toString() : "";
formFilter.position = store.dataProfile.position;
isLoadList.value = true;
http
.post(config.API.kpiRole + `/search`, formFilter)
.then((res) => {
listTarget.value = res.data.result.data;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
totalList.value = res.data.result.total;
isLoadList.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoadList.value = false;
});
}
function fetchRoleByid(id: string) {
showLoader();
isLoad.value = true;
http
.get(config.API.kpiAchievement("role") + `/${id}`)
.then((res) => {
@ -193,12 +197,13 @@ function fetchRoleByid(id: string) {
formDetail.includingName = data.includingName;
formDetail.including = data.including;
listCheckID.value = data.kpiRoleId;
isLoad.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
@ -212,25 +217,25 @@ function fetchListSpecial() {
pageSize: formFilter.pageSize,
page: formFilter.page,
};
showLoader();
isLoadList.value = true;
http
.post(config.API.kpiSpecial + `/search`, body)
.then((res) => {
listTarget.value = res.data.result.data;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
totalList.value = res.data.result.total;
isLoadList.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoadList.value = false;
});
}
function fetchspecialByid(id: string) {
showLoader();
isLoad.value = true;
http
.get(config.API.kpiAchievement("special") + `/${id}`)
.then((res) => {
@ -252,18 +257,19 @@ function fetchspecialByid(id: string) {
formDetail.endDate = data.endDate;
listCheckID.value = data.kpiSpecialId;
isLoad.value = false;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
function clickList(id: string, isData: boolean = false) {
if (!checkDetail.value) {
showLoader();
isLoad.value=true
const url =
numpage.value === 1
? config.API.kpiPlan
@ -301,12 +307,13 @@ function clickList(id: string, isData: boolean = false) {
formDetail.strategyId = data.strategyId;
formDetail.strategyName = data.strategyName;
formDetail.documentInfoEvidence = data.documentInfoEvidence;
isLoad.value=false
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value=false
});
}
}
@ -595,7 +602,7 @@ const title = computed(() => {
<q-separator />
<q-card-section class="q-pa-none">
<q-list separator>
<q-list separator v-if="!isLoadList">
<q-item
dense
v-for="(item, index) in listTarget"
@ -622,6 +629,25 @@ const title = computed(() => {
</q-item-section>
</q-item>
</q-list>
<q-list v-else separator>
<q-item dense v-for="item in 2">
<q-item-section class="q-pa-none">
<div
class="row items-center"
style="min-height: 50px"
>
<div class="col-5">
<q-skeleton type="text" width="50px" />
</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
</q-item-section>
</q-item>
</q-list>
<q-separator />
<div
class="q-pa-lg flex justify-end"
@ -662,18 +688,33 @@ const title = computed(() => {
<div class="q-pa-sm q-col-gutter-lg">
<div class="col-12 row" v-if="numpage !== 3">
<div class="col-4 text-grey-6">หนวยงาน/วนราชการ</div>
<div class="col-8">{{ formDetail.nodeName }}</div>
<div v-if="!isLoad" class="col-8">
{{ formDetail.nodeName }}
</div>
<div class="col-8" v-else>
<q-skeleton type="text" />
</div>
</div>
<div class="col-12 row" v-if="numpage === 1">
<div class="col-4 text-grey-6">ทธศาสตร / แผน</div>
<div class="col-8">{{ formDetail.strategyName }}</div>
<div v-if="!isLoad" class="col-8">
{{ formDetail.strategyName }}
</div>
<div class="col-8" v-else>
<q-skeleton type="text" />
</div>
</div>
<div class="col-12 row">
<div class="col-4 text-grey-6">ลำด/รหสตวช</div>
<div class="col-8">
<q-skeleton
v-if="isLoad"
type="QInput"
height="40px"
/>
<q-input
v-if="numpage === 3"
v-else-if="numpage === 3"
outlined
:readonly="checkDetail"
v-model="formDetail.including"
@ -694,8 +735,13 @@ const title = computed(() => {
<div class="col-12 row">
<div class="col-4 text-grey-6">อตวช</div>
<div class="col-8">
<q-skeleton
v-if="isLoad"
type="QInput"
height="40px"
/>
<q-input
v-if="numpage === 3"
v-else-if="numpage === 3"
outlined
:readonly="checkDetail"
v-model="formDetail.includingName"
@ -715,6 +761,7 @@ const title = computed(() => {
<div class="col-4 text-grey-6">าเปาหมาย</div>
<div class="col-8">
<q-input
v-if="!isLoad"
outlined
v-model="formDetail.target"
bg-color="white"
@ -727,12 +774,14 @@ const title = computed(() => {
hide-bottom-space
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<div class="col-12 row">
<div class="col-4 text-grey-6">หนวยน</div>
<div class="col-8">
<q-input
v-if="!isLoad"
outlined
v-model="formDetail.unit"
bg-color="white"
@ -746,12 +795,14 @@ const title = computed(() => {
hide-bottom-space
reverse-fill-mask
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<div class="col-12 row">
<div class="col-4 text-grey-6">ำหน (อยละ)</div>
<div class="col-8">
<q-input
v-if="!isLoad"
outlined
v-model="formDetail.weight"
bg-color="white"
@ -766,6 +817,7 @@ const title = computed(() => {
lazy-rules
mask="###"
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</div>
@ -784,6 +836,7 @@ const title = computed(() => {
<div class="col-6 text-center text-body2">5</div>
<div class="col-6">
<q-input
v-if="!isLoad"
v-model="formDetail.achievement5"
outlined
dense
@ -793,6 +846,7 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -800,6 +854,7 @@ const title = computed(() => {
<div class="col-6 text-center text-body2">4</div>
<div class="col-6 text-center text-primary">
<q-input
v-if="!isLoad"
v-model="formDetail.achievement4"
outlined
:readonly="checkDetail"
@ -809,6 +864,7 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -816,6 +872,7 @@ const title = computed(() => {
<div class="col-6 text-center text-body2">3</div>
<div class="col-6 text-center text-primary">
<q-input
v-if="!isLoad"
v-model="formDetail.achievement3"
outlined
:readonly="checkDetail"
@ -825,6 +882,7 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -832,6 +890,7 @@ const title = computed(() => {
<div class="col-6 text-center text-body2">2</div>
<div class="col-6 text-center text-primary">
<q-input
v-if="!isLoad"
v-model="formDetail.achievement2"
outlined
:readonly="checkDetail"
@ -841,6 +900,7 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -848,6 +908,7 @@ const title = computed(() => {
<div class="col-6 text-center text-body2">1</div>
<div class="col-6 text-center text-primary">
<q-input
v-if="!isLoad"
v-model="formDetail.achievement1"
outlined
:readonly="checkDetail"
@ -857,12 +918,14 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</q-card>
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="formDetail.meaning"
label="นิยามหรือความหมายของตัวชี้วัด"
type="textarea"
@ -874,10 +937,12 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="formDetail.formula"
label="สูตรคำนวณ"
:readonly="checkDetail"
@ -889,10 +954,12 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<q-input
v-if="!isLoad"
v-model="formDetail.documentInfoEvidence"
label="ข้อมูลเอกสารหลักฐาน"
type="textarea"
@ -904,9 +971,11 @@ const title = computed(() => {
class="inputgreen"
lazy-rules
/>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-3">
<datepicker
v-if="!isLoad"
v-model="formDetail.startDate"
:locale="'th'"
:readonly="checkDetail"
@ -952,9 +1021,11 @@ const title = computed(() => {
</q-input>
</template>
</datepicker>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-3">
<datepicker
v-if="!isLoad"
v-model="formDetail.endDate"
:locale="'th'"
:readonly="checkDetail"
@ -1000,6 +1071,7 @@ const title = computed(() => {
</q-input>
</template>
</datepicker>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</div>

View file

@ -195,9 +195,10 @@ function onSubmit() {
}
}
const isLoadCapacity = ref<boolean>(false);
/** ดึงข้อมูล สมรรถนะ */
function getData() {
showLoader();
isLoadCapacity.value = true;
http
.get(config.API.KpiCapacity + `?type=${type.value}&pageSize=100`)
.then((res) => {
@ -213,7 +214,7 @@ function getData() {
}
})
.finally(() => {
hideLoader();
isLoadCapacity.value = false;
});
}
@ -228,7 +229,9 @@ function filterTxt(val: any) {
}
/** ดึงข้อมูลตามไอดี */
const isLoadById = ref<boolean>(false);
function getDataById() {
isLoadById.value = true;
http
.get(config.API.kpiUserCapacity + `/${idProps.value}`)
.then((res) => {
@ -252,6 +255,7 @@ function getDataById() {
formDetail.definition = target.description;
dataListCapacityDetails.value = dataListCriteria;
isLoadById.value = false;
})
.catch((e) => {})
.finally(() => {});
@ -262,8 +266,10 @@ watch(
() => {
if (modal.value) {
type.value = competencyType.value;
getData();
if (idProps.value) {
isLoadById.value = true;
setTimeout(() => {
getDataById();
}, 500);
@ -407,18 +413,32 @@ watch(
}}
</div>
<div class="col-8">
<span v-if="field == 'type'">{{
formDetail[field]
? store.convertCompetencyType(formDetail[field])
: "-"
}}</span>
<span
v-else-if="field == 'definition'"
v-html="formDetail[field]"
></span>
<span v-else>{{
formDetail[field] ? formDetail[field] : "-"
}}</span>
<span v-if="field == 'type'">
<div v-if="!isLoadById">
{{
formDetail[field]
? store.convertCompetencyType(
formDetail[field]
)
: "-"
}}
</div>
<q-skeleton v-else type="text" />
</span>
<span v-else-if="field == 'definition'">
<div
v-if="!isLoadById"
v-html="formDetail[field]"
></div>
<q-skeleton v-else type="text" />
</span>
<span v-else>
<div v-if="!isLoadById">
{{ formDetail[field] ? formDetail[field] : "-" }}
</div>
<q-skeleton v-else type="text"
/></span>
</div>
</div>
</div>
@ -426,6 +446,7 @@ watch(
<div class="col-4 text-grey-6">ำหน (อยละ)</div>
<div class="col-8">
<q-input
v-if="!isLoadById"
readonly
v-model="weight"
dense
@ -436,10 +457,12 @@ watch(
class="inputgreen"
mask="###"
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-4 text-grey-6">ระดบทคาดหว</div>
<div class="col-8">
<q-select
v-if="!isLoadById"
:readonly="type == 'HEAD' || type == 'GROUP'"
v-model="expectedLevel"
:options="expectedLevelOp"
@ -451,12 +474,14 @@ watch(
hide-bottom-space
class="inputgreen"
/>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</q-card>
</div>
<div class="col-xs-12 col-md-7">
<d-table
v-if="!isLoadById"
flat
bordered
dense
@ -464,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">

View file

@ -60,7 +60,9 @@ let count = ref<number>(0);
* @param index id วข
* @param data อม
*/
const isLoadDetail = ref<boolean>(false);
function clickList(index: string, data: any) {
isLoadDetail.value = true;
listCheck.value = index as string;
formDataView.id = data.id;
@ -76,13 +78,13 @@ function clickList(index: string, data: any) {
reasonCommanderHigh.value = data.reasonCommanderHigh ?? "";
if (count.value >= 1) {
reasonEvaluatorRef.value.reset();
reasonCommanderRef.value.reset();
reasonCommanderHighRef.value.reset();
reasonEvaluatorRef.value && reasonEvaluatorRef.value.reset();
reasonCommanderRef.value && reasonCommanderRef.value.reset();
reasonCommanderHighRef.value && reasonCommanderHighRef.value.reset();
}
showLoader();
count.value++;
setTimeout(() => {
hideLoader();
isLoadDetail.value = false;
}, 100);
}
@ -157,8 +159,9 @@ function closeAdd() {
getList();
}
const isLoad = ref<boolean>(false);
function getList() {
showLoader();
isLoad.value = true;
http
.get(
config.API.kpiCommentP(
@ -171,13 +174,13 @@ function getList() {
.then((res) => {
const data = res.data.result;
listTarget.value = data;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/**
@ -288,7 +291,19 @@ watch(
<q-separator />
<q-card-section class="q-pa-none">
<div v-if="listTarget.length > 0">
<q-list v-if="isLoad" separator>
<q-item dense v-for="item in 2">
<q-item-section class="q-pa-none">
<div class="row items-center" style="min-height: 50px">
<div class="col-12">
<q-skeleton type="text" />
</div>
</div>
</q-item-section>
</q-item>
</q-list>
<div v-else-if="listTarget.length > 0">
<q-list separator dense>
<q-item
v-for="(item, index) in listTarget"
@ -348,11 +363,21 @@ watch(
<div class="row q-pa-md q-col-gutter-sm">
<div class="row col-12 text-weight-medium">
<div class="col-4 text-grey-6">วขอปญหา</div>
<div class="col-8">{{ formDataView.topic }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">
{{ formDataView.topic }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div class="row col-12 text-weight-medium">
<div class="col-4 text-grey-6">รายละเอยดปญหา</div>
<div class="col-8">{{ formDataView.reason }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">
{{ formDataView.reason }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div class="col-12">
<q-separator />
@ -375,6 +400,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
:readonly="
@ -390,6 +416,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้ประเมิน'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div
@ -429,6 +456,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
label="ความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไป"
@ -444,6 +472,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไป'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div
@ -482,6 +511,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
label="ความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไปอีกขั้นหนึ่ง"
@ -497,6 +527,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไปอีกขั้นหนึ่ง'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div

View file

@ -62,7 +62,10 @@ const formDataView = reactive<FormCommentByRole>({
});
let count = ref<number>(0);
const isLoadDetail = ref<boolean>(false);
function clickList(index: string, data: any) {
isLoadDetail.value = true;
listCheck.value = index as string;
formDataView.id = data.id;
@ -80,14 +83,13 @@ function clickList(index: string, data: any) {
reasonCommanderHigh.value = data.reasonCommanderHigh ?? "";
if (count.value >= 1) {
reasonEvaluatorRef.value.reset();
reasonCommanderRef.value.reset();
reasonCommanderHighRef.value.reset();
reasonEvaluatorRef.value && reasonEvaluatorRef.value.reset();
reasonCommanderRef.value && reasonCommanderRef.value.reset();
reasonCommanderHighRef.value && reasonCommanderHighRef.value.reset();
}
count.value++;
showLoader();
setTimeout(() => {
hideLoader();
isLoadDetail.value = false;
}, 100);
}
@ -147,8 +149,9 @@ function closeAdd() {
numLevel.value = "";
}
const isLoad = ref<boolean>(false);
function getList() {
showLoader();
isLoad.value = true;
http
.get(
config.API.kpiCommentP(
@ -161,13 +164,13 @@ function getList() {
.then((res) => {
const data = res.data.result;
listTarget.value = data;
isLoad.value = false;
})
.catch((e) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
function onSubmitComment(role: string) {
@ -313,7 +316,21 @@ watch(
<q-separator />
<q-card-section class="q-pa-none">
<div v-if="listTarget.length > 0">
<q-list v-if="isLoad" separator>
<q-item dense v-for="item in 2">
<q-item-section class="q-pa-none">
<div
class="row items-center"
style="min-height: 50px"
>
<div class="col-12">
<q-skeleton type="text" />
</div>
</div>
</q-item-section>
</q-item>
</q-list>
<div v-else-if="listTarget.length > 0">
<q-list separator dense>
<q-item
v-for="(item, index) in listTarget"
@ -373,7 +390,12 @@ watch(
: "หัวข้อความก้าวหน้า"
}}
</div>
<div class="col-8">{{ formDataView.topic }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">
{{ formDataView.topic }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div class="row col-12 text-weight-medium">
<div class="col-4 text-grey-6">
@ -383,18 +405,29 @@ watch(
: "รายละเอียดความก้าวหน้า"
}}
</div>
<div class="col-8">{{ formDataView.reason }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">{{ formDataView.reason }}</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div
class="row col-12 text-weight-medium"
v-if="type !== 'capacity' && type !== 'development'"
>
<div class="col-4 text-grey-6">คะแนน</div>
<div class="col-8">{{ formDataView.score }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">{{ formDataView.score }}</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div class="row col-12 text-weight-medium">
<div class="col-4 text-grey-6">สราง</div>
<div class="col-8">{{ formDataView.createdFullName }}</div>
<div class="col-8">
<div v-if="!isLoadDetail">
{{ formDataView.createdFullName }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
<div
@ -422,6 +455,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
:readonly="
@ -437,6 +471,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้ประเมิน'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div
@ -475,6 +510,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
label="ความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไป"
@ -490,6 +526,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไป'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div
@ -527,6 +564,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoadDetail"
outlined
dense
label="ความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไปอีกขั้นหนึ่ง"
@ -542,6 +580,7 @@ watch(
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณากรอกความคิดเห็นของผู้บังคับบัญชาเหนือขึ้นไปอีกขั้นหนึ่ง'}`,]"
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div

View file

@ -30,6 +30,8 @@ const props = defineProps({
const route = useRoute();
const idKpi = ref<string>(route.params.id.toLocaleString());
const isLoadMain = defineModel<boolean>("isLoadMain", { required: true });
const isLoad = ref<boolean>(false);
const development = ref<string[]>([]); //
const reasonDevelopment70 = ref<string>(""); // ()
const reasonDevelopment20 = ref<string>(""); // (Coach/Mentor/Consulting)
@ -185,8 +187,6 @@ function close() {
reasonDevelopment20.value = "";
reasonDevelopment10.value = "";
development.value = [];
props.getAll?.();
}
/** บันทึกข้อมูลการพัฒนาตน */
@ -198,7 +198,8 @@ function onSubmit() {
) {
dialogMessageNotify($q, "กรุณาเลือกวิธีการพัฒนา อย่างน้อย 1 ตัวเลือก");
} else {
dialogConfirm($q, () => {
dialogConfirm($q, async () => {
showLoader();
const url = id.value
? config.API.kpiAchievementDevelop + `/${id.value}`
: config.API.kpiAchievementDevelop;
@ -220,9 +221,9 @@ function onSubmit() {
selectTypeYear: formData.year ? formData.year.toString() : null,
selectTypeId: projectName.value ? projectName.value.id : null,
};
showLoader();
http[id.value ? "put" : "post"](url, body)
.then((res) => {
await http[id.value ? "put" : "post"](url, body)
.then(async () => {
await props?.getAll?.();
success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
@ -236,9 +237,10 @@ function onSubmit() {
}
}
const isLoadYear = ref<boolean>(false);
async function getDataByYear() {
if (formData.year) {
showLoader();
isLoadYear.value = true;
http
.get(config.API.developmentMain + `/done?year=${formData.year}`)
.then(async (res) => {
@ -249,13 +251,14 @@ async function getDataByYear() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadYear.value = false;
});
}
}
const isLoadProject = ref<boolean>(false);
function getProjectDetail(val: any) {
showLoader();
isLoadProject.value = true;
http
.get(config.API.developmentMain + `/tab3_1/${val.id}`)
.then((res) => {
@ -283,7 +286,7 @@ function getProjectDetail(val: any) {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadProject.value = false;
});
}
@ -305,7 +308,7 @@ watch(
() => id.value,
(i) => {
if (i) {
showLoader();
isLoad.value = true;
http
.get(config.API.kpiAchievementDevelop + `/${id.value}`)
.then(async (res) => {
@ -342,13 +345,14 @@ watch(
)
? data.reasonDevelopment10
: "";
isLoad.value = false;
}, 500);
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
}
@ -367,6 +371,7 @@ watch(
<div class="row q-col-gutter-sm">
<div class="col-3">
<q-select
v-if="!isLoad"
class="inputgreen"
outlined
dense
@ -379,9 +384,11 @@ watch(
v-model="choice"
>
</q-select>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-3" v-if="choice == 'PROJECT'">
<datepicker
v-if="!isLoad"
menu-class-name="modalfix"
v-model="formData.year"
:locale="'th'"
@ -419,9 +426,11 @@ watch(
</q-input>
</template>
</datepicker>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-3" v-if="choice == 'PROJECT'">
<q-select
v-if="!isLoadYear"
outlined
dense
:rules="[(val:string) => !!val || `${'กรุณาเลือกโครงการ/หลักสูตรการฝึกอบรม'}`,]"
@ -446,9 +455,11 @@ watch(
</q-item>
</template>
</q-select>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-12">
<q-input
v-if="!isLoad && !isLoadProject"
v-model="formData.name"
outlined
dense
@ -459,6 +470,7 @@ watch(
label="ชื่อเรื่อง/เนื้อเรื่อง/หัวข้อการพัฒนา"
>
</q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
<div class="col-12">
<span class="text-weight-medium">การพฒนา</span>
@ -469,6 +481,7 @@ watch(
>70 การลงมอปฏ (โดยผงคบบญชามอบหมาย)</span
>
<q-option-group
v-if="!isLoad && !isLoadProject"
class="check_box q-mt-sm"
keep-color
color="primary"
@ -477,16 +490,31 @@ watch(
:options="projectTechniquesOp1"
type="checkbox"
/>
<q-list v-else class="list-c">
<q-item
class="q-pa-none"
style="max-width: 300px; height: 30px"
v-for="item in 11"
>
<q-item-section>
<q-skeleton type="text" />
</q-item-section>
</q-item>
</q-list>
<div class="row q-pb-md" v-if="checkOtherBox11">
<div class="offset-4 col-8 q-mt-sm relative-position">
<div class="other_custom_input">
<q-input
v-if="!isLoad && !isLoadProject"
v-model="reasonDevelopment70"
dense
outlined
class="inputgreen"
label="กรุณาระบุ"
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</div>
@ -496,6 +524,7 @@ watch(
>20 การเรยนรจากผ (Coach/Mentor/Consulting)</span
>
<q-option-group
v-if="!isLoad && !isLoadProject"
class="check_box q-mt-sm"
keep-color
color="primary"
@ -504,16 +533,29 @@ watch(
:options="projectTechniquesOp2"
type="checkbox"
/>
<q-list v-else class="list-c">
<q-item
class="q-pa-none"
style="max-width: 300px; height: 30px"
v-for="item in 5"
>
<q-item-section>
<q-skeleton type="text" />
</q-item-section>
</q-item>
</q-list>
<div class="row q-pb-md" v-if="checkOtherBox12">
<div class="offset-4 col-8 q-mt-sm relative-position">
<div class="other_custom_input">
<q-input
v-if="!isLoad && !isLoadProject"
v-model="reasonDevelopment20"
dense
outlined
class="inputgreen"
label="กรุณาระบุ"
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</div>
@ -521,6 +563,7 @@ watch(
<div class="col-12 col-sm-6 col-md-6 col-lg-4">
<span class="text-weight-medium">10 การฝกอบรมอนๆ</span>
<q-option-group
v-if="!isLoad && !isLoadProject"
class="check_box q-mt-sm"
keep-color
color="primary"
@ -529,16 +572,29 @@ watch(
:options="projectTechniquesOp3"
type="checkbox"
/>
<q-list v-else class="list-c">
<q-item
class="q-pa-none"
style="max-width: 300px; height: 30px"
v-for="item in 7"
>
<q-item-section>
<q-skeleton type="text" />
</q-item-section>
</q-item>
</q-list>
<div class="row q-pb-md" v-if="checkOtherBox13">
<div class="offset-4 col-8 q-mt-sm relative-position">
<div class="other_custom_input">
<q-input
v-if="!isLoad && !isLoadProject"
v-model="reasonDevelopment10"
dense
outlined
class="inputgreen"
label="กรุณาระบุ"
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</div>
@ -546,6 +602,7 @@ watch(
</div>
<div class="col-12">
<q-input
v-if="!isLoad && !isLoadProject"
label="เป้าหมายการนำไปพัฒนางาน"
v-model="formData.target"
outlined
@ -556,6 +613,7 @@ watch(
lazy-rules
hide-bottom-space
></q-input>
<q-skeleton v-else type="QInput" height="150px" />
</div>
<div class="col-12">
<q-card bordered>
@ -573,6 +631,7 @@ watch(
</div>
<div class="col-8">
<q-input
v-if="!isLoad && !isLoadProject"
class="inputgreen"
v-model="formData.achievement10"
outlined
@ -582,6 +641,7 @@ watch(
lazy-rules
hide-bottom-space
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -591,6 +651,7 @@ watch(
</div>
<div class="col-8">
<q-input
v-if="!isLoad && !isLoadProject"
class="inputgreen"
v-model="formData.achievement5"
outlined
@ -600,6 +661,7 @@ watch(
lazy-rules
hide-bottom-space
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
<q-separator />
@ -609,6 +671,7 @@ watch(
</div>
<div class="col-8">
<q-input
v-if="!isLoad && !isLoadProject"
class="inputgreen"
v-model="formData.achievement0"
outlined
@ -618,6 +681,7 @@ watch(
lazy-rules
hide-bottom-space
></q-input>
<q-skeleton v-else type="QInput" height="40px" />
</div>
</div>
</q-card>
@ -640,6 +704,9 @@ watch(
:deep(.check_box .q-checkbox) {
align-items: start;
}
:deep(.list-c .q-item) {
min-height: 30px;
}
.other_custom_input {
position: absolute;

View file

@ -13,20 +13,14 @@ import DialogHeader from "@/components/DialogHeader.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>("");
const rows = ref<any[]>([]);
const isLoad = ref<boolean>(false);
const visibleColumns = ref<string[]>([
"commandName",
"agency",
@ -134,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;
@ -164,7 +135,7 @@ function close() {
/** ดึงข้อมูล */
function getData() {
showLoader();
isLoad.value = true;
http
.get(config.API.orgAssistance(store.dataEvaluation.profileId))
.then((res) => {
@ -175,14 +146,14 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
watch(
() => modal.value,
(n) => {
if (n == true) {
if (n) {
getData();
}
}
@ -208,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">

View file

@ -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";
@ -17,14 +17,14 @@ import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentP
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 props = defineProps({
fetchList: { type: Function, required: true },
});
@ -136,7 +136,7 @@ async function onEvaluate() {
function onDelete(id: string) {
dialogRemove($q, async () => {
try {
showLoader();
isLoad.value = true;
const url =
numpage.value === 1
? config.API.kpiAchievement("planned") + `/${id}`
@ -151,7 +151,6 @@ function onDelete(id: string) {
} catch (err) {
messageError($q, err);
} finally {
hideLoader();
}
});
}
@ -244,7 +243,7 @@ const isEditStep3 = computed(() => {
<d-table
ref="table"
:columns="columns"
:rows="rows"
:rows="rows || []"
:filter="filterKeyword"
row-key="id"
flat
@ -253,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">

View file

@ -123,6 +123,7 @@ const visibleColumns = ref<string[]>(
const typeCompetency = ref<string>("");
const rows = ref<any>([]);
const isLoad = ref<any>([]);
const lists = ref<any>([]);
const modalProgress = ref<boolean>(false);
const modalProblem = ref<boolean>(false);
@ -157,6 +158,7 @@ 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) => {
@ -215,6 +217,7 @@ function getData(type: string) {
: 0;
}
}
isLoad.value[type] = false;
});
}
@ -232,7 +235,7 @@ function onEdit(data: FormCapacityList, type: string) {
*/
function onDelete(id: string, type: string) {
dialogRemove($q, () => {
showLoader();
isLoad.value[type] = true;
http
.delete(config.API.kpiUserCapacity + `/${id}`)
.then((res) => {
@ -293,7 +296,12 @@ function onLevel(num: number, list: any) {
}
watch(
() => [store.dataEvaluation.posTypeName, store.dataEvaluation.posExecutiveName, store.dataEvaluation.position, store.dataEvaluation.posLevelName], // posTypeName posExecutiveName
() => [
store.dataEvaluation.posTypeName,
store.dataEvaluation.posExecutiveName,
store.dataEvaluation.position,
store.dataEvaluation.posLevelName,
], // posTypeName posExecutiveName
(newValue) => {
if (!newValue) return; //
const posTypeName = newValue[0];
@ -326,26 +334,25 @@ watch(
competencyType.value =
position === "ผู้ตรวจราชการกรุงเทพมหานคร" || position === "ผู้ตรวจราชการ"
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "INSPECTOR"
)
: posExecutiveName === "ผู้อำนวยการเขต"
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "DIRECTOR"
)
: posTypeName === "อำนวยการ" ||
posTypeName === "บริหาร" ||
(posTypeName === "ทั่วไป" &&
posLevelName === "อาวุโส" &&
posExecutiveName != null) ||
(posTypeName === "วิชาการ" &&
posExecutiveName != null)
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "EXECUTIVE"
)
: competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "GROUP"
);
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "INSPECTOR"
)
: posExecutiveName === "ผู้อำนวยการเขต"
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "DIRECTOR"
)
: posTypeName === "อำนวยการ" ||
posTypeName === "บริหาร" ||
(posTypeName === "ทั่วไป" &&
posLevelName === "อาวุโส" &&
posExecutiveName != null) ||
(posTypeName === "วิชาการ" && posExecutiveName != null)
? competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "EXECUTIVE"
)
: competencyTypeList.filter(
(x: DataOptions) => x.id === "HEAD" || x.id === "GROUP"
);
for (let index = 0; index < competencyType.value.length; index++) {
const element = competencyType.value[index];
@ -391,19 +398,21 @@ watch(
</q-btn>
</div>
</q-card-section>
<q-card-section class="q-pa-sm">
<d-table
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">

View file

@ -24,29 +24,23 @@ 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,
default: false,
});
const isLoad = ref<boolean>(false);
const modalProgress = ref<boolean>(false);
const modalProblem = ref<boolean>(false);
const type = ref<string>("");
const idList = ref<string>("");
const isEditStep1 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "NEW" &&
store.rolePerson === "USER" &&
store.tabMain === "1")
store.dataEvaluation.evaluationStatus === "NEW" &&
store.rolePerson === "USER" &&
store.tabMain === "1"
);
});
@ -148,6 +142,7 @@ function onEdit(id: string) {
/** ดึงข้อมูลพัฒนา */
function getDevelop() {
isLoad.value = true;
http
.get(config.API.kpiAchievementDevelop + `?id=${evaluationId.value}`)
.then((res) => {
@ -159,6 +154,7 @@ function getDevelop() {
0
);
isLoad.value = false;
store.devScoreVal =
data.length !== 0 ? totalSummary / rows.value.length : 0;
});
@ -173,7 +169,7 @@ function onEvaluate() {
*/
function onDelete(id: string) {
dialogRemove($q, () => {
showLoader();
isLoad.value = true;
http
.delete(config.API.kpiAchievementDevelop + `/${id}`)
.then((res) => {
@ -182,10 +178,9 @@ function onDelete(id: string) {
})
.catch((e) => {
messageError($q, e);
isLoad.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
});
}
@ -253,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">
@ -341,7 +337,11 @@ onMounted(() => {
dense
@click="openPopupProgress(props.row.id)"
>
<q-tooltip>{{store.tabMain == '3' ? `บันทึกเหตุการณ์/พฤติกรรม/เหตุผล` :'บันทึกเหตุการณ์/พฤติกรรม'}}</q-tooltip>
<q-tooltip>{{
store.tabMain == "3"
? `บันทึกเหตุการณ์/พฤติกรรม/เหตุผล`
: "บันทึกเหตุการณ์/พฤติกรรม"
}}</q-tooltip>
</q-btn>
</div>
@ -505,6 +505,7 @@ onMounted(() => {
v-model:modal="modalDevelop"
v-model:id="idEditDevelop"
:get-all="getDevelop"
v-model:isLoadMain="isLoad"
/>
<DialogEvalutionDevelop

View file

@ -66,6 +66,11 @@ const commanderHighId = ref<any>(null); // ตัวแปรเก็บ id ผ
const imgProfile = ref<string>(""); //
/** ตัวแปรโหลด */
const isLoad = ref<boolean>(false);
const isLoadCommander = ref<boolean>(false);
const isLoadAvatar = ref<boolean>(false); //
const formProfile = reactive<FormProfile>({
fullName: "",
position: "",
@ -95,7 +100,9 @@ async function fetchEvaluation() {
}
async function getAvatar(id: string) {
isLoadAvatar.value = true;
await http
.get(config.API.orgCheckAvatar(id))
.then(async (res) => {
const data = await res.data.result;
@ -105,12 +112,15 @@ async function getAvatar(id: string) {
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoadAvatar.value = false;
});
}
/** ดึงข้อมูล เพื่อเก็บรูปโปรไฟล์ */
async function fetchProfile(id: string, avatarName: string) {
http
await http
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, avatarName))
.then(async (res) => {
store.dataEvaluation.avartar = res.data.downloadUrl;
@ -162,6 +172,7 @@ function onSubmit() {
/** ดึงข้อมูล ผู้ประเมิน */
async function getOrgOp() {
isLoadCommander.value = true;
http
.get(config.API.Kpiorg)
.then((res) => {
@ -199,9 +210,11 @@ async function getOrgOp() {
.find(
(i: EvaOptionType) => i.id == store.dataEvaluation.commanderHighId
);
isLoadCommander.value = false;
})
.catch((e) => {
messageError($q, e);
isLoadCommander.value = false;
})
.finally(() => {});
}
@ -453,8 +466,9 @@ const evaluator = ref<EvaluatorType>({
* อมลของผประเม
* @param id อมลของผประเม
*/
const isLoadModal = ref<boolean>(false);
async function fetchProfileEvaluator(id: string) {
showLoader();
isLoadModal.value = true;
http
.get(config.API.orgPosition + `/${id}`)
.then(async (res) => {
@ -467,12 +481,13 @@ async function fetchProfileEvaluator(id: string) {
evaluator.value.isPosmasterAct = data.isPosmasterAct;
evaluator.value.posmasterAct = data.posmasterAct;
evaluator.value.org = await findOrgNameHtml(data);
isLoadModal.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadModal.value = false;
});
}
@ -583,19 +598,20 @@ async function uploadFileDoc(uploadUrl: string, file: any) {
}
/** ดึงข้อมูล */
const isLoadUpload = ref<boolean>(false);
async function getData() {
showLoader();
isLoadUpload.value = true;
await http
.get(config.API.file("แบบกำหนดข้อตกลง", "KPI", id.value))
.then((res) => {
fileList.value = res.data;
isLoadUpload.value = false;
})
.catch((e) => {
messageError($q, e);
isLoadUpload.value = false;
})
.finally(() => {
hideLoader();
});
.finally(() => {});
}
/**
@ -654,7 +670,6 @@ function onResize(size: { width: any; height: any }) {
}
onMounted(async () => {
showLoader();
store.isUpdate = false;
await getAll();
});
@ -689,7 +704,8 @@ onMounted(async () => {
<q-card bordered flat class="relative-position">
<div class="row justify-center q-pa-md" v-if="!$q.screen.gt.xs">
<q-avatar :size="sizeImg">
<q-img :src="imgProfile" v-if="imgProfile !== ''" />
<q-skeleton type="circle" size="100px" v-if="isLoadAvatar" />
<q-img :src="imgProfile" v-else-if="imgProfile !== ''" />
<q-img src="@/assets/avatar_user.jpg" v-else />
</q-avatar>
</div>
@ -699,7 +715,8 @@ onMounted(async () => {
style="left: 2%; top: 50%; transform: translateY(-50%)"
>
<q-avatar :size="sizeImg">
<q-img :src="imgProfile" v-if="imgProfile !== ''" />
<q-skeleton type="circle" size="100px" v-if="isLoadAvatar" />
<q-img :src="imgProfile" v-else-if="imgProfile !== ''" />
<q-img src="@/assets/avatar_user.jpg" v-else />
</q-avatar>
</div>
@ -1028,7 +1045,7 @@ onMounted(async () => {
/>
<q-separator />
<q-card-section>
<div class="column q-gutter-sm">
<div v-if="!isLoadCommander" class="column q-gutter-sm">
<div class="row">
<div class="col-10">
<q-select
@ -1179,6 +1196,18 @@ onMounted(async () => {
</div>
</div>
</div>
<div
v-else
class="row q-col-gutter-xs items-center"
v-for="item in 3"
>
<div class="col-10">
<q-skeleton type="QInput" height="40px" />
</div>
<div class="col-2 q-pa-sm text-right">
<q-skeleton type="QRadio" />
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions
@ -1219,23 +1248,42 @@ onMounted(async () => {
<div class="col-3">ตำแหนงทางการบรหาร</div>
<div class="col-3">งก</div>
</div>
<div class="row">
<div class="row q-col-gutter-x-sm">
<div class="col-3">
{{ evaluator.position ? evaluator.position : "-" }}
<div v-if="!isLoadModal">
{{ evaluator.position ? evaluator.position : "-" }}
</div>
<q-skeleton v-else type="text" />
</div>
<div class="col-3">
{{ evaluator.posTypeName ? evaluator.posTypeName : "-" }}
{{
evaluator.posLevelName ? ` (${evaluator.posLevelName})` : "-"
}}
<div v-if="!isLoadModal">
{{ evaluator.posTypeName ? evaluator.posTypeName : "-" }}
{{
evaluator.posLevelName
? ` (${evaluator.posLevelName})`
: "-"
}}
</div>
<q-skeleton v-else type="text" />
</div>
<div class="col-3">
{{
evaluator.posExecutiveName ? evaluator.posExecutiveName : "-"
}}
<div v-if="!isLoadModal">
{{
evaluator.posExecutiveName
? evaluator.posExecutiveName
: "-"
}}
</div>
<q-skeleton v-else type="text" />
</div>
<div class="col-3 text-html">
{{ evaluator.org ? evaluator.org : "-" }}
<div v-if="!isLoadModal">
{{ evaluator.org ? evaluator.org : "-" }}
</div>
<q-skeleton v-else type="text" />
</div>
</div>
@ -1243,9 +1291,12 @@ onMounted(async () => {
<div class="col-12">กษาการในตำแหน/การรกษาราชการแทน</div>
</div>
<div class="row">
<div v-if="isLoadModal" class="col-12">
<q-skeleton type="text" />
</div>
<div
class="col-12"
v-if="evaluator.isPosmasterAct"
v-else-if="evaluator.isPosmasterAct"
v-for="(data, index) in evaluator.posmasterAct"
:key="index"
>
@ -1305,7 +1356,11 @@ onMounted(async () => {
</q-file>
</div>
<div v-if="fileList.length > 0" class="col-xs-12 row">
<div class="col-12" v-if="isLoadUpload">
<q-skeleton height="50px" />
</div>
<div v-else-if="fileList.length > 0" class="col-xs-12 row">
<q-list class="full-width rounded-borders" bordered separator>
<q-item
clickable

View file

@ -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,
@ -30,6 +30,8 @@ const { showLoader, hideLoader, messageError, date2Thai, dialogConfirm } =
mixin;
/** Table*/
const isLoadOp = ref<boolean>(false);
const isLoad = ref<boolean>(false);
const rows = ref<MainListKpi[]>([]);
const visibleColumns = ref<string[]>([
"createdAt",
@ -104,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[]>([]);
@ -139,29 +140,29 @@ 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,
});
/**
* งขอมลรอบการประเม
* @param type
*/
const isLoadDialog = ref<boolean>(false);
async function fetchRoundOption(type: string) {
const y = type === "main" ? year.value : yearDialog.value;
showLoader();
type == "main" && (isLoadOp.value = true);
type == "dialog" && (isLoadDialog.value = true);
await http
.get(
config.API.kpiPeriod + `?page=${1}&pageSize=${10}&keyword=${""}&year=${y}`
@ -196,18 +197,17 @@ async function fetchRoundOption(type: string) {
messageError($q, err);
})
.finally(() => {
hideLoader();
type == "main" && (isLoadOp.value = false);
type == "dialog" && (isLoadDialog.value = false);
});
}
/**
* fetch รายการขอรบประเมนผลการปฏราชการระดบบคคล
*/
/** ฟังก์ชันดึงข้อมูลรายการขอรับประเมินผลการปฏิบัติราชการระดับบุคคล*/
async function fetchList() {
showLoader();
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,
@ -219,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;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
/** เลือกรอบการประเมิน */
function changRound() {
formQuery.page = 1;
pagination.value.page = 1;
fetchList();
}
@ -327,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
@ -415,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()]);
@ -456,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>
@ -520,6 +514,7 @@ onMounted(async () => {
<div class="items-center col-12 row q-col-gutter-sm">
<div class="col-xs-12 col-md-2">
<q-select
v-if="!isLoadOp"
v-model="round"
outlined
label="รอบการประเมิน"
@ -531,6 +526,7 @@ onMounted(async () => {
map-options
@update:model-value="changRound"
/>
<q-skeleton v-else type="QInput" height="40px" bordered />
</div>
<div class="col-xs-12 col-md-3">
@ -549,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 = ''),
@ -581,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 = ''),
@ -610,7 +606,6 @@ onMounted(async () => {
ref="table"
:columns="columns"
:rows="rows"
:filter="filterKeyword"
row-key="id"
flat
bordered
@ -618,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">
@ -662,20 +658,6 @@ 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>
</div>
</div>
@ -736,6 +718,7 @@ onMounted(async () => {
<div class="col-12">
<q-select
v-if="!isLoadDialog"
:readonly="yearDialog === null"
v-model="formRound.kpiPeriodId"
outlined
@ -749,6 +732,7 @@ onMounted(async () => {
:rules="[(val:DataOptions) => !!val.id || `${'กรุณาเลือกรอบการประเมิน'}`]"
@update:model-value="checkClosed"
/>
<q-skeleton type="QInput" height="40px" v-else />
</div>
<div class="col-12">

View file

@ -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,14 +84,14 @@ const columns = ref<QTableProps["columns"]>([
]);
const totalList = ref<number>(0);
const maxPage = ref<number>(1);
/**
* งขอมลรายการขอรบประเมนผลการปฏราชการระดบบคคล
* @param type
*/
const isLoadOp = ref<boolean>(false);
async function fetchRoundOption() {
showLoader();
isLoadOp.value = true;
await http
.get(
config.API.kpiPeriod +
@ -125,13 +122,14 @@ async function fetchRoundOption() {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoadOp.value = false;
});
}
/** ดึงข้อมูล list */
const isLoad = ref<boolean>(false);
async function fetchList() {
showLoader();
isLoad.value = true;
const body = {
page: store.formQuery.page,
pageSize: store.formQuery.pageSize,
@ -155,7 +153,6 @@ 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;
})
@ -163,7 +160,7 @@ async function fetchList() {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
@ -173,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;
@ -190,13 +178,6 @@ async function onChangTab() {
await fetchList();
}
watch(
() => store.formQuery.pageSize,
() => {
fetchList();
}
);
onMounted(async () => {
await fetchRoundOption();
});
@ -221,7 +202,7 @@ onMounted(async () => {
<div class="col-12">
<q-card bordered class="q-pa-md">
<div class="items-center col-12 row q-col-gutter-sm q-mb-sm">
<div class="items-center col-12 row q-gutter-sm q-mb-sm">
<datepicker
class="col-md-1 col-xs-12"
v-model="store.yearRound"
@ -260,6 +241,7 @@ onMounted(async () => {
</template>
</datepicker>
<q-select
v-if="!isLoadOp"
class="col-md-2 col-xs-12"
v-model="store.formQuery.round"
outlined
@ -272,7 +254,12 @@ onMounted(async () => {
map-options
@update:model-value="changRound"
/>
<q-skeleton
v-else
class="col-md-2 col-xs-12"
type="QInput"
height="40px"
/>
<q-space />
<q-input
@ -339,9 +326,8 @@ onMounted(async () => {
:rows="dataListMain"
:formQuery="store.formQuery"
:total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList"
:is-load="isLoad"
/>
</q-tab-panel>
@ -352,9 +338,8 @@ onMounted(async () => {
:rows="dataListMain"
:formQuery="store.formQuery"
:total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList"
:is-load="isLoad"
/>
</q-tab-panel>
@ -365,9 +350,8 @@ onMounted(async () => {
:rows="dataListMain"
:formQuery="store.formQuery"
:total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList"
:is-load="isLoad"
/>
</q-tab-panel>
@ -378,9 +362,8 @@ onMounted(async () => {
:rows="dataListMain"
:formQuery="store.formQuery"
:total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList"
:is-load="isLoad"
/>
</q-tab-panel>
@ -391,9 +374,8 @@ onMounted(async () => {
:rows="dataListMain"
:formQuery="store.formQuery"
:total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList"
:is-load="isLoad"
/>
</q-tab-panel>
</q-tab-panels>

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ import type {
} from "@/modules/09_scholarship/interface/index/Main";
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError } = mixin;
const { messageError } = mixin;
const router = useRouter();
const $q = useQuasar();
@ -24,6 +24,7 @@ const currentPage = ref<number>(1);
const page = ref<number>(1);
const rowsPerPage = ref<number>(10);
const isLoad = ref<boolean>(false);
const rows = ref<Scholarship[]>([]);
const year = ref<number>(0);
const type = ref<string>("DOMESTICE");
@ -85,7 +86,7 @@ const visibleColumns = ref<string[]>(["scholarshipYear", "scholarshipType"]);
/** ดึงข้อมูล */
async function getData() {
showLoader();
isLoad.value = true;
await http
.get(
config.API.developmentScholarship +
@ -98,7 +99,7 @@ async function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoad.value = false;
});
}
@ -106,40 +107,20 @@ 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() {
if (dataStore.profileId) {
profilId.value = dataStore.profileId;
} else {
showLoader();
try {
isLoad.value = true;
try {
if (!dataStore.profileId) {
const res = await http.get(config.API.profilePosition());
dataStore.profileId = res.data.result.profileId;
profilId.value = dataStore.profileId;
} catch (e) {
messageError($q, e);
} finally {
hideLoader();
}
profilId.value = dataStore.profileId;
await getData();
} catch (e) {
messageError($q, e);
} finally {
isLoad.value = false;
}
await getData();
}
function convertType(val: string) {
@ -253,7 +234,7 @@ onMounted(async () => {
/>
</div>
<div>
<div class="col-12">
<d-table
flat
bordered
@ -263,21 +244,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

View file

@ -1,19 +1,20 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useQuasar, type QTableColumn, type QTableProps } from "quasar";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
/** import Type */
import type { InformationData } from "@/interface/Main";
const link = ref<string>("");
/** import Component */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const $q = useQuasar();
const dataStore = useDataStore();
const mixin = useCounterMixin();
const {
showLoader,
hideLoader,
@ -21,16 +22,23 @@ const {
date2Thai,
dialogConfirm,
success,
} = mixin;
const editPhone = ref<boolean>(false);
const editEmail = ref<boolean>(false);
const rowsHistory = ref<any[]>([]);
const rowsHistoryData = ref<any[]>([]);
const modalHistory = ref<boolean>(false);
const phone = ref<string>("");
const email = ref<string>("");
} = useCounterMixin();
const link = ref<string>(""); // link
const editPhone = ref<boolean>(false); //
const editEmail = ref<boolean>(false); //
const rowsHistory = ref<any[]>([]); //
const rowsHistoryData = ref<any[]>([]); // ( filter)
const modalHistory = ref<boolean>(false); // modal
const phone = ref<string>(""); //
const email = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const mainEmail = ref<string>(""); //
const mainPhone = ref<string>(""); //
const isValidPhone = ref<boolean>(true); // validate
const isValidEmail = ref<boolean>(true); // validate
const emailVerify = ref<string | null>(null); //
/** ตัวแปรข้อมูล */
const formDataInformation = reactive<InformationData>({
rank: "", //
@ -48,8 +56,6 @@ const formDataInformation = reactive<InformationData>({
phone: "", //
email: "",
});
const emailVerify = ref<string | null>(null);
const visibleColumnsHistory = ref<string[]>([
"citizenId",
"prefix",
@ -237,27 +243,19 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory() {
modalHistory.value = true;
}
const mainEmail = ref<string>("");
const mainPhone = ref<string>("");
/** ตรวจสอบอีเมล */
const isCheckEmail = computed(() => {
return mainEmail.value === formDataInformation.email ? true : false;
});
/** ตรวจสอบเบอร์โทร */
const isCheckPhone = computed(() => {
console.log("mainPhone", mainPhone.value);
console.log("formDataInformation", formDataInformation.phone);
return mainPhone.value === formDataInformation.phone ? true : false;
});
/** get data */
/** ฟังก์ชันดึงข้อมูลประวัติส่วนตัว */
async function getData() {
showLoader();
isLoading.value = true;
await http
.get(config.API.dataUserInformationByType(link.value))
.then(async (res) => {
@ -285,24 +283,27 @@ async function getData() {
phone.value = data.phone;
emailVerify.value = data.statusEmail;
hideLoader();
})
.catch((e) => {
messageError($q, e);
hideLoader();
})
.finally(() => {});
.finally(() => {
isLoading.value = false;
});
}
/** get history */
function getHistory() {
/** ฟังก์ชันดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
const url =
dataStore.officerType == "OFFICER"
? config.API.dataUserInformatioHistory("")
: config.API.dataUserInformatioHistory("-employee");
showLoader();
http
await http
.get(url)
.then((res) => {
const data = res.data.result;
@ -313,14 +314,16 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
const isValidPhone = ref<boolean>(true); // validate
const isValidEmail = ref<boolean>(true); // validate
/** ฟังก์ชันเปิด modal ประวัติการแก้ไขข้อมูลส่วนตัว */
function onHistory() {
modalHistory.value = true;
}
/** บันทึกเบอร์โทร */
/** ฟังก์ชันบันทึกเบอร์โทร */
async function onSavePhone() {
if (!formDataInformation.phone || formDataInformation.phone.length != 10) {
isValidPhone.value = false;
@ -353,7 +356,7 @@ async function onSavePhone() {
}
}
/** บันทึก email */
/** ฟังก์ชันบันทึก email */
async function onSaveEmail() {
if (!formDataInformation.email) {
isValidEmail.value = false;
@ -388,6 +391,7 @@ onMounted(async () => {
await getData();
});
</script>
<template>
<div class="col-12">
<q-toolbar class="q-px-none">
@ -402,13 +406,17 @@ onMounted(async () => {
dense
round
size="14px"
:loading="isLoading"
@click="onHistory"
>
<q-tooltip>ประวแกไขขอมลสวนต</q-tooltip>
</q-btn>
</q-toolbar>
<q-card bordered class="bg-grey-1 q-pa-md">
<div class="row">
<div v-if="isLoading">
<q-skeleton height="160px" />
</div>
<div v-else class="row">
<div class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<div class="row">
<div class="col-4 text-grey-6 text-weight-medium">
@ -670,5 +678,6 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,33 +1,26 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import http from "@/plugins/http";
import config from "@/app.config";
/** import type*/
import { useQuasar, type QTableProps } from "quasar";
import type { ChangNameRows } from "@/modules/10_registry/interface/response/01_Information";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const rows = ref<ChangNameRows[]>([]);
const rowsData = ref<ChangNameRows[]>([]);
const idByrow = ref<string>("");
const filter = ref<string>("");
const rowsHistory = ref<ChangNameRows[]>([]);
const rowsHistoryData = ref<ChangNameRows[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); // true = desktop mode, false = mobile mode
const isLoading = ref<boolean>(false); //
const link = ref<string>(""); // -
const rows = ref<ChangNameRows[]>([]); // -
const rowsData = ref<ChangNameRows[]>([]); // -
const filter = ref<string>(""); //
const visibleColumns = ref<string[]>([
"prefix",
"firstName",
@ -98,93 +91,10 @@ const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"prefix",
"firstName",
"lastName",
"status",
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "prefix",
align: "left",
label: "คำนำหน้าชื่อ",
sortable: true,
field: "prefix",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "firstName",
align: "left",
label: "ชื่อ",
sortable: true,
field: "firstName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastName",
align: "left",
label: "นามสกุล",
sortable: true,
field: "lastName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "status",
align: "left",
label: "สถานะการเปลี่ยนชื่อ",
sortable: true,
field: "status",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
format: (v) => date2Thai(v),
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByrow.value = id;
}
/** get data */
/** ฟังก์ชันดึงข้อมูลประวัติการเปลี่ยนชื่อ */
async function getData() {
showLoader();
http
isLoading.value = true;
await http
.get(config.API.dataUserChangeNameByType(link.value))
.then((res) => {
const data = res.data.result;
@ -195,33 +105,11 @@ async function getData() {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 2000);
});
}
/** get history */
function getHistory() {
showLoader();
http
.get(
config.API.dataUserChangeNameHistoryByType(link.value) +
`/${idByrow.value}`
)
.then((res) => {
const data = res.data.result;
rowsHistory.value = data;
rowsHistoryData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -230,9 +118,10 @@ function onSearch() {
);
}
/**
* งกโหลไฟลเอกสารหลกฐาน
/***
* งกดาวนโหลไฟลเอกสารหลกฐาน
* @param id รายการทองการโหลด
* @param profileId รหสโปรไฟลของผใช
*/
async function onDownloadFile(id: string, profileId: string) {
showLoader();
@ -263,8 +152,8 @@ onMounted(async () => {
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -301,97 +190,94 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
bordered
virtual-scroll
: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"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-if="mode" v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="(col, index) in props.cols" :key="col.name">
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="green"
flat
dense
round
icon="mdi-file-document-outline"
@click="onDownloadFile(props.row.id, props.row.profileId)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
</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>
<q-list dense class="q-mt-lg relative-position">
<q-td auto-width>
<q-btn
color="green"
flat
dense
round
class="absolute_button"
icon="mdi-file-document-outline"
@click="onDownloadFile(props.row.id, props.row.profileId)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
</q-td>
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section>
<q-item-label class="text-grey-6 text-weight-medium">{{
col.label
}}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label class="text-dark text-weight-medium">{{
col.value ? col.value : "-"
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</template>
</d-table>
<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"
:pagination="pagination"
:loading="isLoading"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-if="mode" v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="(col, index) in props.cols" :key="col.name">
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="green"
flat
dense
round
icon="mdi-file-document-outline"
@click="onDownloadFile(props.row.id, props.row.profileId)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
</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>
<q-list dense class="q-mt-lg relative-position">
<q-td auto-width>
<q-btn
color="green"
flat
dense
round
class="absolute_button"
icon="mdi-file-document-outline"
@click="onDownloadFile(props.row.id, props.row.profileId)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
</q-td>
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section>
<q-item-label class="text-grey-6 text-weight-medium">{{
col.label
}}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label class="text-dark text-weight-medium">{{
col.value ? col.value : "-"
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</template>
</d-table>
</div>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขการเปลี่ยนชื่อ-นามสกุล'"
:getData="getHistory"
:rows="rowsHistory"
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -6,8 +6,8 @@ import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
/** import type */
import type {
Address,
Provinces,
@ -15,28 +15,26 @@ import type {
SubDistricts,
} from "@/modules/10_registry/interface/response/01_Information";
//history dialog
/** import component */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonAddress from "@/modules/10_registry/components/skeleton/Address.vue";
const link = ref<string>("");
const store = useRegistryInFormationStore();
const dataStore = useDataStore();
const rowsHistory = ref<any[]>([]);
const rowsHistoryData = ref<any[]>([]);
const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const dataStore = useDataStore();
const { messageError, date2Thai } = useCounterMixin();
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const link = ref<string>(""); //
const rowsHistory = ref<any[]>([]); //
const rowsHistoryData = ref<any[]>([]); //
const modalHistory = ref<boolean>(false); //
const formData = reactive({
registrationAddress: "", //
registrationProvince: "", //
registrationDistrict: "", // /
registrationSubDistrict: "", // /
registrationZipCode: "", //
currentAddress: "", //
currentProvince: "", //
currentDistrict: "", // /
@ -44,11 +42,11 @@ const formData = reactive({
currentZipCode: "", //
});
const provinceData = ref<Provinces[]>([]);
const districtRegistration = ref<Districts[]>([]);
const districtCurrent = ref<Districts[]>([]);
const subDistrictRegistration = ref<SubDistricts[]>([]);
const subDistrictCurrent = ref<SubDistricts[]>([]);
const provinceData = ref<Provinces[]>([]); //
const districtRegistration = ref<Districts[]>([]); // /
const districtCurrent = ref<Districts[]>([]); // /
const subDistrictRegistration = ref<SubDistricts[]>([]); // /
const subDistrictCurrent = ref<SubDistricts[]>([]); // /
const visibleColumnsHistory = ref<string[]>([
"currentAddress",
@ -65,7 +63,6 @@ const visibleColumnsHistory = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "registrationAddress",
@ -217,21 +214,18 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory() {
modalHistory.value = true;
}
/** get data */
/** ฟังก์ชันดึงข้อมูลที่อยู่ */
async function getData() {
showLoader();
http
await http
.get(config.API.dataUserAddressByType(link.value))
.then((res) => {
.then(async (res) => {
const data: Address = res.data.result;
fetchDistrict(data.registrationProvinceId, "1");
fetchDistrict(data.currentProvinceId, "2");
fetchSubDistrict(data.registrationDistrictId, "1");
fetchSubDistrict(data.currentDistrictId, "2");
await Promise.all([
fetchDistrict(data.registrationProvinceId, "1"),
fetchDistrict(data.currentProvinceId, "2"),
fetchSubDistrict(data.registrationDistrictId, "1"),
fetchSubDistrict(data.currentDistrictId, "2"),
]);
formData.registrationAddress = data.registrationAddress;
formData.registrationProvince = data.registrationProvinceId;
@ -247,42 +241,41 @@ async function getData() {
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 2000);
});
}
/** get history */
function getHistory() {
/** ฟังก์ชันดึงข้อมูลประวัติที่อยู่ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
const url =
dataStore.officerType == "OFFICER"
? config.API.dataUserHistory("")
: config.API.dataUserHistory("-employee");
showLoader();
http
await http
.get(url)
.then((res) => {
const data = res.data.result;
rowsHistory.value = data;
console.log("🚀 ~ .then ~ data:", data);
rowsHistoryData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
*function fetch อมลจงหว
*/
function fetchProvince() {
http
function onHistory() {
modalHistory.value = true;
}
/** ฟังก์ชันดึงข้อมูลจังหวัด */
async function fetchProvince() {
await http
.get(config.API.profileNewProvince)
.then((res) => {
const data = res.data.result;
@ -294,13 +287,13 @@ function fetchProvince() {
}
/**
* function fetch อมลอำเภอ
* งกนดอมลอำเภอ
* @param id งหว
* @param position อยตามทะเบยนบาน,อยจจ
*/
function fetchDistrict(id: string | null, position: string) {
async function fetchDistrict(id: string | null, position: string) {
if (!id) return;
http
await http
.get(config.API.profileNewDistrictByPId(id))
.then((res) => {
const data = res.data.result.districts;
@ -316,13 +309,13 @@ function fetchDistrict(id: string | null, position: string) {
}
/**
* function fetch อมลอำเภ
* งกนดอมลอำเภ
* @param id อำเภอ
* @param position อยตามทะเบยนบาน,อยจจ
*/
function fetchSubDistrict(id: string | null, position: string) {
async function fetchSubDistrict(id: string | null, position: string) {
if (!id) return;
http
await http
.get(config.API.profileNewSubDistrictByDId(id))
.then((res) => {
const data = res.data.result.subDistricts;
@ -338,8 +331,8 @@ function fetchSubDistrict(id: string | null, position: string) {
}
/**
* function แปลงชอจงหว
* @param id
* งกแปลงชอจงหว
* @param id รหสจงหว
*/
function convertProvinceName(id: string) {
const province = provinceData.value.find((e: Provinces) => e.id === id);
@ -347,8 +340,8 @@ function convertProvinceName(id: string) {
}
/**
* function แปลงชออำเภอ
* @param id
* งกแปลงชออำเภอ
* @param id รหสอำเภอ
*/
function convertDistrictName(id: string, type: string) {
const data =
@ -358,8 +351,8 @@ function convertDistrictName(id: string, type: string) {
}
/**
* function แปลงชอตำบล
* @param id
* งก แปลงชอตำบล
* @param id รหสตำบล
*/
function convertSubDistrictName(id: string, type: string) {
const data =
@ -369,9 +362,14 @@ function convertSubDistrictName(id: string, type: string) {
}
onMounted(async () => {
isLoading.value = true;
link.value = await dataStore.getProFileType();
await fetchProvince();
await getData();
try {
await fetchProvince();
await getData();
} finally {
isLoading.value = false;
}
});
</script>
<template>
@ -386,6 +384,7 @@ onMounted(async () => {
dense
round
size="14px"
:loading="isLoading"
@click="onHistory"
>
<q-tooltip>ประวอมลทอย</q-tooltip>
@ -402,7 +401,8 @@ onMounted(async () => {
</q-item>
<q-separator />
<q-card-section>
<div class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<SkeletonAddress v-if="isLoading" />
<div v-else class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">
อยตามทะเบยนบาน
@ -481,7 +481,8 @@ onMounted(async () => {
</q-item>
<q-separator />
<q-card-section>
<div class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<SkeletonAddress v-if="isLoading" />
<div v-else class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">
อยจจ
@ -547,5 +548,6 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,33 +1,28 @@
<script setup lang="ts">
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
import { useDataStore } from "@/stores/data";
import { useCounterMixin } from "@/stores/mixin";
import type { FormChildren } from "@/modules/10_registry/interface/index/Family";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonFamily from "@/modules/10_registry/components/skeleton/Family.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const idFamily = ref<string>("");
const store = useRegistryInFormationStore();
const dataStore = useDataStore();
const rowsHistory = ref<any[]>([]);
const rowsHistoryData = ref<any[]>([]);
const { messageError, date2Thai } = useCounterMixin();
const typeForm = ref<string>("");
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const fatherData = reactive<any>({
const link = ref<string>(""); //
const idFamily = ref<string>(""); // ID
const rowsHistory = ref<any[]>([]); //
const rowsHistoryData = ref<any[]>([]); //
const typeForm = ref<string>(""); // (father, mother, couple, children)
const modalHistory = ref<boolean>(false); //
const fatherData = reactive({
isLive: null,
citizenId: "",
prefix: "",
@ -36,7 +31,7 @@ const fatherData = reactive<any>({
job: "",
profileId: "",
});
const motherData = reactive<any>({
const motherData = reactive({
isLive: null,
citizenId: "",
prefix: "",
@ -45,7 +40,7 @@ const motherData = reactive<any>({
job: "",
profileId: "",
});
const coupleData = reactive<any>({
const coupleData = reactive({
isLive: null,
citizenId: "",
prefix: "",
@ -56,7 +51,6 @@ const coupleData = reactive<any>({
statusMarital: "",
profileId: "",
});
const childData = ref<FormChildren[]>([]);
const visibleColumnsHistory = ref<string[]>([
@ -161,21 +155,26 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
const checkFatherData = ref<boolean>(false);
const checkMotherData = ref<boolean>(false);
const checkCoupleData = ref<boolean>(false);
const checkChildData = ref<boolean>(false);
const checkFatherData = ref<boolean>(false); //
const checkMotherData = ref<boolean>(false); //
const checkCoupleData = ref<boolean>(false); //
const checkChildData = ref<boolean>(false); //
function onHistory(type: string, id: string) {
modalHistory.value = true;
typeForm.value = type;
idFamily.value = id ? id : "user";
}
const isLoadingHistory = ref<boolean>(false); //
const isLoading = reactive({
father: false,
mother: false,
couple: false,
});
/** get data */
/**
* งกนดงขอมลสมาชกในครอบคร
* @param type ประเภทขอม (father, mother, couple, children)
*/
async function getData(type: string) {
showLoader();
http
(isLoading as any)[type] = true;
await http
.get(config.API.dataUserFamilyByType(link.value, type))
.then((res) => {
const data = res.data.result;
@ -219,14 +218,24 @@ async function getData(type: string) {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 2000);
(isLoading as any)[type] = false;
});
}
/** get history */
function getHistory() {
/**
* งกนเปดประวการแกไขขอม
* @param type ประเภทขอม (father, mother, couple, children)
* @param id ID ของครอบคร (ใชสำหรบบตร)
*/
function onHistory(type: string, id: string) {
modalHistory.value = true;
typeForm.value = type;
idFamily.value = id ? id : "user";
}
/** ฟังก์ชันดึงประวัติการแก้ไขข้อมูล */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
const url =
@ -238,8 +247,7 @@ function getHistory() {
idFamily.value
);
showLoader();
http
await http
.get(url)
.then((res) => {
const data = res.data.result;
@ -261,7 +269,7 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
@ -292,12 +300,14 @@ onMounted(async () => {
flat
dense
round
:isLoading="isLoading.father"
size="14px"
@click="onHistory('father', '')"
>
<q-tooltip>ประวการแกไขขอมลบดา</q-tooltip>
</q-btn>
<div class="col-12">
<SkeletonFamily v-if="isLoading.father" :type="'father'" />
<div class="col-12" v-else>
<q-card bordered class="bg-grey-1 q-pa-sm">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 q-gutter-y-sm">
@ -366,11 +376,13 @@ onMounted(async () => {
dense
round
size="14px"
:isLoading="isLoading.mother"
@click="onHistory('mother', '')"
>
<q-tooltip>ประวการแกไขขอมลมารดา</q-tooltip>
</q-btn>
<div class="col-12">
<SkeletonFamily v-if="isLoading.mother" :type="'mother'" />
<div v-else class="col-12">
<q-card bordered class="bg-grey-1 q-pa-sm">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 q-gutter-y-sm">
@ -441,12 +453,14 @@ onMounted(async () => {
flat
dense
round
:isLoading="isLoading.couple"
size="14px"
@click="onHistory('couple', '')"
>
<q-tooltip>ประวการแกไขขอมลคสมรส</q-tooltip>
</q-btn>
<div class="col-12">
<SkeletonFamily v-if="isLoading.couple" :type="'couple'" />
<div v-else class="col-12">
<q-card bordered class="bg-grey-1 q-pa-sm">
<div class="row">
<div class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
@ -632,6 +646,7 @@ onMounted(async () => {
? columnsHistory
: columnsHistory?.filter((e) => e.name !== 'lastNameOld')
"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,12 +1,11 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useDataStore } from "@/stores/data";
//history dialog
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useDataStore } from "@/stores/data";
import { useCounterMixin } from "@/stores/mixin";
import type { EducationProfile } from "@/modules/10_registry/interface/index/Main";
@ -16,20 +15,18 @@ const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const rows = ref<EducationProfile[]>([]);
const rowsData = ref<EducationProfile[]>([]);
const rowsHistory = ref<EducationProfile[]>([]);
const rowsHistoryData = ref<EducationProfile[]>([]);
const idByRow = ref<string>("");
const filter = ref<string>("");
const mode = ref<boolean>($q.screen.gt.xs);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const { messageError, date2Thai, onSearchDataTable } = mixin;
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<EducationProfile[]>([]); //
const rowsData = ref<EducationProfile[]>([]); //
const rowsHistory = ref<EducationProfile[]>([]); //
const rowsHistoryData = ref<EducationProfile[]>([]); //
const idByRow = ref<string>(""); // ID
const filter = ref<string>(""); //
const mode = ref<boolean>($q.screen.gt.xs); // true = desktop mode, false = mobile mode
const modalHistory = ref<boolean>(false); //
const visibleColumns = ref<string[]>([
"educationLevel",
"institute",
@ -266,10 +263,26 @@ const columns = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const pagination = ref({
// sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"educationLevel",
"institute",
"degree",
"field",
"gpa",
"country",
"duration",
"durationYear",
"other",
"fundName",
"isEducation",
"isHigh",
"endDate",
"startDate",
"finishDate",
"note",
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "educationLevel",
@ -486,37 +499,11 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const visibleColumnsHistory = ref<string[]>([
"educationLevel",
"institute",
"degree",
"field",
"gpa",
"country",
"duration",
"durationYear",
"other",
"fundName",
"isEducation",
"isHigh",
"endDate",
"startDate",
"finishDate",
"note",
"lastUpdateFullName",
"lastUpdatedAt",
]);
/** เปิด dialog ประวัติ */
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
/** ฟังก์ชันดึงข้อมูลการศึกษา */
async function getData() {
showLoader();
http
isLoading.value = true;
await http
.get(config.API.dataUserEducationsByType(link.value))
.then((res) => {
const data = res.data.result;
@ -527,16 +514,25 @@ async function getData() {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 2000);
isLoading.value = false;
});
}
/**
* เป dialog ประวการศกษา
* @param id ID ของแถวทกเลอกสำหรบดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get history */
function getHistory() {
showLoader();
http
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserEducationsHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -547,10 +543,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันค้นหาข้อมูลการศึกษา */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -561,7 +558,6 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
await getData();
});
</script>
@ -603,6 +599,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -611,10 +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"
v-model:pagination="pagination"
:loading="isLoading"
row-key="id"
:pagination="{ page: 1, rowsPerPage: 10 }"
>
<template v-slot:header="props">
<q-tr :props="props">
@ -687,6 +686,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขประวัติการศึกษา'"
@ -695,6 +695,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,33 +1,34 @@
<script setup lang="ts">
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
/** import type */
import type { AbilityRows } from "@/modules/10_registry/interface/index/Main";
//history dialog
/** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const rows = ref<AbilityRows[]>([]);
const rowsData = ref<AbilityRows[]>([]);
const rowsHistory = ref<AbilityRows[]>([]);
const rowsHistoryData = ref<AbilityRows[]>([]);
const idByRow = ref<string>("");
const filter = ref<string>("");
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); // true = desktop mode, false = mobile mode
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<AbilityRows[]>([]); //
const rowsData = ref<AbilityRows[]>([]); //
const rowsHistory = ref<AbilityRows[]>([]); //
const rowsHistoryData = ref<AbilityRows[]>([]); //
const idByRow = ref<string>(""); // id
const filter = ref<string>(""); //
const modalHistory = ref<boolean>(false); // modal
const visibleColumns = ref<string[]>([
"field",
"detail",
@ -187,14 +188,9 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
showLoader();
isLoading.value = true;
http
.get(config.API.dataUserAbilityByType(link.value))
.then((res) => {
@ -206,16 +202,25 @@ async function getData() {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 2000);
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนเป modal ประวการแกไขความสามารถพเศษ
* @param id ID ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันดึงข้อมูลประวัติการแก้ไขความสามารถพิเศษ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserAbilityHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -226,10 +231,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันค้นหาข้อมูล */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -241,6 +247,7 @@ function onSearch() {
/**
* งกนโหลไฟลเอกสารหลกฐาน
* @param id รายการทองการโหลด
* @param profileId ID ของโปรไฟลองการโหลด
*/
async function onDownloadFile(id: string, profileId: string) {
showLoader();
@ -272,7 +279,6 @@ onMounted(async () => {
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -309,6 +315,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -320,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">
@ -422,6 +431,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขความสามารถพิเศษ'"
@ -430,8 +440,10 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -7,30 +7,26 @@ import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
import type {
ProfileAppointment,
FormDataGovernment,
} from "@/modules/10_registry/interface/index/Main";
//history dialog
/** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import GovernmentSkeleton from "@/modules/10_registry/components/skeleton/Government.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataPerson = useDataStore();
const checkType = ref<boolean>(
dataPerson.officerType == "OFFICER" ? true : false
);
const store = useRegistryInFormationStore();
const { showLoader, hideLoader, messageError, date2Thai, dateToISO } = mixin;
const { messageError, date2Thai, dateToISO } = useCounterMixin();
const rowsHistory = ref<ProfileAppointment[]>([]);
const rowsHistoryData = ref<ProfileAppointment[]>([]);
const modalHistory = ref<boolean>(false);
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rowsHistory = ref<ProfileAppointment[]>([]); //
const rowsHistoryData = ref<ProfileAppointment[]>([]); //
const modalHistory = ref<boolean>(false); // modal
/** ตัวแปรข้อมูล */
const formData = reactive<FormDataGovernment>({
org: "",
positionField: "",
@ -138,7 +134,6 @@ const columnsHistory = ref<QTableProps["columns"]>([
]);
/** ไม่เเน่ใจ ใช้เเบบไหน คอมเม้นไว้ก่อน */
// const columnsHistory = ref<QTableProps["columns"]>([
// {
// name: "oc",
@ -343,15 +338,14 @@ const columnsHistory = ref<QTableProps["columns"]>([
// a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
// },
// ]);
const checkType = ref<boolean>(
dataPerson.officerType == "OFFICER" ? true : false
);
function onHistory() {
modalHistory.value = true;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserGovernmentByType(link.value))
.then((res) => {
const data = res.data.result;
@ -378,18 +372,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
/** ฟังก์ชันเปิด modal ประวัติข้อมูล */
function onHistory() {
modalHistory.value = true;
}
/** ฟังก์ชันดึงประวัติข้อมูลราชการ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
const url =
dataPerson.officerType == "OFFICER"
? config.API.dataUserGovernmentHistory("")
: config.API.dataUserGovernmentHistory("-employee");
showLoader();
http
await http
.get(url)
.then((res) => {
const data = res.data.result;
@ -400,13 +401,13 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
@ -421,12 +422,15 @@ onMounted(async () => {
dense
round
size="14px"
:isLoading="isLoading"
@click="onHistory"
>
<q-tooltip>ประวอมลราชการ</q-tooltip>
</q-btn>
</q-toolbar>
<q-card bordered class="bg-grey-1 q-pa-md">
<GovernmentSkeleton v-if="isLoading" />
<q-card v-else bordered class="bg-grey-1 q-pa-md">
<div class="row q-col-gutter-y-sm">
<div class="col-12 col-sm-12 col-md-6">
<div class="row q-col-gutter-y-sm">
@ -584,5 +588,6 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,10 +1,10 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
@ -12,27 +12,24 @@ import type { DisciplineDetail } from "@/modules/10_registry/interface/index/Mai
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
useCounterMixin();
const rows = ref<DisciplineDetail[]>([]);
const rowsData = ref<DisciplineDetail[]>([]);
const idByRow = ref<string>("");
const filter = ref<string>("");
const rowsHistory = ref<DisciplineDetail[]>([]);
const rowsHistoryData = ref<DisciplineDetail[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const fileGroup = ref<string>("เอกสารวินัย");
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); // ;
const rows = ref<DisciplineDetail[]>([]); //
const rowsData = ref<DisciplineDetail[]>([]); //
const idByRow = ref<string>(""); // ID
const filter = ref<string>(""); //
const rowsHistory = ref<DisciplineDetail[]>([]); //
const rowsHistoryData = ref<DisciplineDetail[]>([]); //
const fileGroup = ref<string>("เอกสารวินัย"); //
const modalHistory = ref<boolean>(false); // / modal
const visibleColumns = ref<string[]>([
"level",
"detail",
@ -142,15 +139,10 @@ const pagination = ref({
sortBy: "lastUpdatedAt",
});
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลวินัย */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserDisciplineByType(link.value))
.then((res) => {
const data = res.data.result;
@ -161,14 +153,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* เป modal ประวการแกไข
* @param id ID ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserDisciplineHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -179,15 +182,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนดาวนโหลดไฟลเอกสารหลกฐาน
* @param id ID ของไฟลองการดาวนโหลด
* @param profileId ID ของโปรไฟล
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (e) {
messageError($q, e);
} finally {
hideLoader();
}
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -198,7 +214,7 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
getData();
await getData();
});
</script>
<template>
@ -237,6 +253,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -248,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">
@ -302,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>
@ -349,6 +369,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขวินัย'"
@ -357,6 +378,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumns"
:columns="columns"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,34 +1,31 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import type { LeaveFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const idByRow = ref<string>("");
const rows = ref<LeaveFormType[]>([]);
const rowsData = ref<LeaveFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<any[]>([]);
const rowsHistoryData = ref<any[]>([]);
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<LeaveFormType[]>([]); //
const rowsData = ref<LeaveFormType[]>([]); // ()
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<LeaveFormType[]>([]); //
const rowsHistoryData = ref<LeaveFormType[]>([]); // ()
const modalHistory = ref<boolean>(false); // modal
const visibleColumns = ref<string[]>([
"no",
"typeLeave",
@ -39,7 +36,6 @@ const visibleColumns = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -136,7 +132,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"no",
"typeLeave",
@ -243,15 +238,10 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลการลา */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserLeaveByType(link.value))
.then((res) => {
const data = res.data.result;
@ -275,14 +265,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนสำหรบเป modal ประวการลา
* @param id ID ของการลา
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการลา */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserLeaveHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -306,10 +307,15 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบแสดงสถานะการลา
* @param val าสถานะการลา
* @return สถานะการลาในรปแบบขอความ
*/
function statusLeave(val: string) {
switch (val) {
case "waitting":
@ -325,6 +331,11 @@ function statusLeave(val: string) {
}
}
/**
* งกนสำหรบแปลงชวงวนทเปนรปแบบไทย
* @param val วงวนทองการแปลงเปนรปแบบไทย
* @return วงวนทในรปแบบไทย
*/
function dateThaiRange(val: [Date, Date]) {
if (val === null) {
} else if (date2Thai(val[0]) === date2Thai(val[1])) {
@ -334,6 +345,7 @@ function dateThaiRange(val: [Date, Date]) {
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -344,11 +356,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1">การลา</span>
@ -383,6 +394,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -394,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">
@ -494,6 +508,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขการลา'"
@ -503,6 +518,7 @@ onMounted(async () => {
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:type="'Leave'"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,35 +1,35 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataStore = useDataStore();
const idByRow = ref<string>("");
const rows = ref<DutyFormType[]>([]);
const rowsData = ref<DutyFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<DutyFormType[]>([]);
const rowsHistoryData = ref<DutyFormType[]>([]);
const $q = useQuasar();
const mode = ref<any>($q.screen.gt.xs);
const mixin = useCounterMixin();
const dataStore = useDataStore();
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
useCounterMixin();
const mode = ref<any>($q.screen.gt.xs); // true = desktop, false = mobile
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<DutyFormType[]>([]); //
const rowsData = ref<DutyFormType[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<DutyFormType[]>([]); //
const rowsHistoryData = ref<DutyFormType[]>([]); //
const modalHistory = ref<boolean>(false); // / modal
const fileGroup = ref<string>("เอกสารปฏิบัติราชการพิเศษ"); //
const visibleColumns = ref<string[]>([
"dateStart",
"dateEnd",
@ -137,7 +137,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"dateStart",
"dateEnd",
@ -243,17 +242,10 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
const fileGroup = ref<string>("เอกสารปฏิบัติราชการพิเศษ");
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลปฏิบัติราชการ */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserDutyByType(link.value))
.then((res) => {
const data = res.data.result;
@ -264,14 +256,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนสำหรบเป modal ประวการแกไข
* @param id ID ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserDutyHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -282,15 +285,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบดาวนโหลดไฟล
* @param id ID ของแถวทเลอก
* @param profileId ID ของโปรไฟลเลอก
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (e) {
messageError($q, e);
} finally {
hideLoader();
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง*/
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -301,11 +317,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -342,6 +357,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -353,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">
@ -464,6 +482,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,36 +1,35 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
/** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataStore = useDataStore();
const idByRow = ref<string>("");
const rows = ref<DutyFormType[]>([]);
const rowsData = ref<DutyFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<DutyFormType[]>([]);
const rowsHistoryData = ref<DutyFormType[]>([]);
const $q = useQuasar();
const mode = ref<any>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const dataStore = useDataStore();
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const modalHistory = ref<boolean>(false);
const mode = ref<boolean>($q.screen.gt.xs); // true if screen is larger than xs
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<DutyFormType[]>([]); //
const rowsData = ref<DutyFormType[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<DutyFormType[]>([]); //
const rowsHistoryData = ref<DutyFormType[]>([]); //
const modalHistory = ref<boolean>(false); // modal
const checkType = ref<boolean>(
dataStore.officerType == "OFFICER" ? true : false
);
/** ตัวแปรข้อมูล */
const visibleColumns = ref<String[]>([
"dateStart",
"dateEnd",
@ -103,10 +102,6 @@ const columns = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"dateStart",
"dateEnd",
@ -116,7 +111,6 @@ const visibleColumnsHistory = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "dateStart",
@ -188,16 +182,14 @@ const columnsHistory = ref<QTableProps["columns"]>([
format: (v) => date2Thai(v, false, true),
},
]);
const pagination = ref({
sortBy: "lastUpdatedAt",
});
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserActpositionByType(link.value))
.then((res) => {
const data = res.data.result;
@ -208,14 +200,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* เป modal ประวการแกไข
* @param id ID ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserActpositionHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -226,10 +229,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันสำหรับค้นหาข้อมูล */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -240,12 +244,11 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -282,6 +285,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -293,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">
@ -363,6 +369,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขรักษาการในตำแหน่ง'"
@ -371,6 +378,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>

View file

@ -1,33 +1,34 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
/** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const $q = useQuasar();
const link = ref<string>("");
const dataStore = useDataStore();
const idByRow = ref<string>("");
const rows = ref<DutyFormType[]>([]);
const rowsData = ref<DutyFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<DutyFormType[]>([]);
const rowsHistoryData = ref<DutyFormType[]>([]);
const $q = useQuasar();
const mode = ref<any>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); // false;
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<DutyFormType[]>([]); //
const rowsData = ref<DutyFormType[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<DutyFormType[]>([]); //
const rowsHistoryData = ref<DutyFormType[]>([]); //
const modalHistory = ref<boolean>(false); // modal
const visibleColumns = ref<string[]>([
"commandName",
"agency",
@ -135,7 +136,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"commandName",
"agency",
@ -241,15 +241,10 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูลช่วยราชการ */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserAssistanceByType(link.value))
.then((res) => {
const data = res.data.result;
@ -260,14 +255,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนเป modal ประวการแกไข
* @param id ID ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserAssistanceHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -278,13 +284,14 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนโหลไฟลเอกสารหลกฐาน
* @param id รายการทองการโหลด
* @param profileId ID ของโปรไฟล
*/
async function onDownloadFile(id: string, profileId: string) {
showLoader();
@ -310,6 +317,7 @@ async function onDownloadFile(id: string, profileId: string) {
});
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -320,11 +328,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataStore.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1">วยราชการ</span>
@ -359,6 +366,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -370,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">
@ -469,6 +479,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขรายการช่วยราชการ'"
@ -477,6 +488,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,49 +1,48 @@
<script setup lang="ts">
import { useQuasar, type QTableColumn } from "quasar";
import { ref, onMounted, computed } from "vue";
import { ref, onMounted, computed, reactive } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useGovernmentPosDataStore } from "@/modules/10_registry/store/Position";
import type {
SalaryFormType,
CardDataPos,
} from "@/modules/10_registry/interface/index/Main";
import type { DataCommandCode } from "@/modules/10_registry/interface/response/Main";
//history dialog
/**import components*/
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const dataPerson = useDataStore();
const store = useGovernmentPosDataStore();
const mixin = useCounterMixin();
const {
showLoader,
hideLoader,
messageError,
date2Thai,
onSearchDataTable,
formatDatePosition,
findOrgName,
findOrgNameHtml,
} = mixin;
} = useCounterMixin();
const idByRow = ref<string>("");
const rows = ref<SalaryFormType[]>([]);
const rowsData = ref<SalaryFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<SalaryFormType[]>([]);
const rowsHistoryData = ref<SalaryFormType[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const checkType = ref<boolean>(
dataPerson.officerType == "OFFICER" ? true : false
);
const modalHistory = ref<boolean>(false);
); //
const mode = ref<boolean>($q.screen.gt.xs); // xs
const isLoading = reactive({
position: false, //
tenure: false, //
});
const isLoadingHistory = ref<boolean>(false); //
const link = ref<string>(""); // link
const rows = ref<SalaryFormType[]>([]); //
const rowsData = ref<SalaryFormType[]>([]); //
const idByRow = ref<string>(""); // id
const filter = ref<string>(""); // input
const rowsHistory = ref<SalaryFormType[]>([]); //
const rowsHistoryData = ref<SalaryFormType[]>([]); //
const modalHistory = ref<boolean>(false); // dialog
const cardData = ref<CardDataPos[]>([
{
label: "ระยะเวลาดำรงตำแหน่งในสายงาน",
@ -58,7 +57,6 @@ const cardData = ref<CardDataPos[]>([
data: [],
},
]);
const baseColumns = ref<QTableColumn[]>([
{
name: "commandDateAffect",
@ -315,7 +313,6 @@ const baseVisibleColumns = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columns = computed<QTableColumn[]>(() => {
if (!checkType.value) {
if (baseColumns.value) {
@ -349,59 +346,9 @@ const columnsHistory = computed<QTableColumn[]>(() => {
});
const visibleColumnsHistory = ref<string[]>(baseVisibleColumns.value);
/** เปิด dialog ประวัติ*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
.get(config.API.dataUserPosition(link.value))
.then((res) => {
const data = res.data.result;
rows.value = data;
rowsData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
/** get history */
function getHistory() {
showLoader();
http
.get(config.API.dataUserSalaryHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
rowsHistory.value = data;
rowsHistoryData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
rowsData.value,
columns.value ? columns.value : []
);
}
/** ฟังก์ชันดึงข้อมูลระยะเวลาดำรงตำแหน่ง */
async function fetchDataTenure() {
console.log(link.value);
isLoading.tenure = true;
await http
.get(config.API.salaryTenurePosition(link.value))
.then((res) => {
@ -440,40 +387,78 @@ async function fetchDataTenure() {
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoading.tenure = false;
});
}
/** function fetch ข้อมูลประเภทคำสั่ง*/
async function fetchDataCommandCode() {
if (store.commandCodeData.length > 0) return false;
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
isLoading.position = true;
await http
.get(config.API.orgCommandCode)
.get(config.API.dataUserPosition(link.value))
.then((res) => {
const data = res.data.result;
const DataCommandCode = data.filter((e: DataCommandCode) =>
store.positionCode.includes(e.code)
);
const options = DataCommandCode.map((e: DataCommandCode) => ({
id: e.code.toString(),
name: e.name,
}));
store.commandCodeData = options;
rows.value = data;
rowsData.value = data;
})
.catch((err) => {
messageError($q, err);
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoading.position = false;
});
}
/**
* เป dialog ประว
* @param id id ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันดึงข้อมูลประวัติ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserSalaryHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
rowsHistory.value = data;
rowsHistoryData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
rowsData.value,
columns.value ? columns.value : []
);
}
onMounted(async () => {
link.value = await dataPerson.getProFileType();
if (link.value === "-employee") {
cardData.value.splice(2, 1);
try {
link.value = await dataPerson.getProFileType();
if (link.value === "-employee") {
cardData.value.splice(2, 1);
}
await Promise.all([getData(), fetchDataTenure()]);
} catch (error) {
messageError($q, error);
}
getData();
fetchDataTenure();
fetchDataCommandCode();
});
</script>
@ -492,7 +477,15 @@ onMounted(async () => {
</div>
<div class="col-12"><q-separator /></div>
<q-card-section class="q-pt-none" style="min-height: 200px">
<li v-for="data in item.data">{{ data.name }} {{ data.time }}</li>
<q-skeleton
v-if="isLoading.tenure"
type="text"
class="q-mb-sm"
style="width: 100%"
/>
<li v-else v-for="data in item.data">
{{ data.name }} {{ data.time }}
</li>
</q-card-section>
</q-card>
</div>
@ -543,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">
@ -664,6 +660,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { useQuasar, type QTableColumn } from "quasar";
import { ref, onMounted, computed } from "vue";
import { useQuasar, type QTableColumn } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
@ -9,40 +9,32 @@ import { useDataStore } from "@/stores/data";
import type { SalaryFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const dataPerson = useDataStore();
const mixin = useCounterMixin();
const {
showLoader,
hideLoader,
messageError,
date2Thai,
onSearchDataTable,
findOrgName,
findOrgNameHtml,
} = mixin;
const idByRow = ref<string>("");
const rows = ref<SalaryFormType[]>([]);
const rowsData = ref<SalaryFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<SalaryFormType[]>([]);
const rowsHistoryData = ref<SalaryFormType[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const checkType = ref<boolean>(
dataPerson.officerType == "OFFICER" ? true : false
);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
} = useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<SalaryFormType[]>([]); //
const rowsData = ref<SalaryFormType[]>([]); // ()
const filter = ref<string>(""); //
const idByRow = ref<string>(""); //id
const rowsHistory = ref<SalaryFormType[]>([]); //
const rowsHistoryData = ref<SalaryFormType[]>([]); // ()
const modalHistory = ref<boolean>(false); // dialog
const salaryText = computed(() => {
return link.value == "" ? "เงินเดือน" : "ค่าจ้าง";
});
const baseColumns = ref<QTableColumn[]>([
{
name: "commandDateAffect",
@ -330,20 +322,6 @@ const visibleColumns = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columns = computed(() => {
if (link.value === "-employee") {
if (baseColumns.value) {
return baseColumns.value.filter(
(column) =>
column.name !== "positionSalaryAmount" &&
column.name !== "mouthSalaryAmount"
);
}
}
return baseColumns.value;
});
const visibleColumnsHistory = ref<string[]>([
"commandDateAffect",
"posNumCodeSit",
@ -363,20 +341,6 @@ const visibleColumnsHistory = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = computed(() => {
if (link.value === "-employee") {
if (baseColumnsHistory.value) {
return baseColumnsHistory.value.filter(
(column: QTableColumn) =>
column.name !== "positionSalaryAmount" &&
column.name !== "mouthSalaryAmount"
);
}
}
return baseColumns.value;
});
const baseColumnsHistory = ref<QTableColumn[]>([
{
name: "commandDateAffect",
@ -639,16 +603,36 @@ const baseColumnsHistory = ref<QTableColumn[]>([
},
]);
/** เปิด dialog ประวัติ*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
const columns = computed(() => {
if (link.value === "-employee") {
if (baseColumns.value) {
return baseColumns.value.filter(
(column) =>
column.name !== "positionSalaryAmount" &&
column.name !== "mouthSalaryAmount"
);
}
}
return baseColumns.value;
});
/** get data */
function getData() {
showLoader();
http
const columnsHistory = computed(() => {
if (link.value === "-employee") {
if (baseColumnsHistory.value) {
return baseColumnsHistory.value.filter(
(column: QTableColumn) =>
column.name !== "positionSalaryAmount" &&
column.name !== "mouthSalaryAmount"
);
}
}
return baseColumns.value;
});
/*** ฟังก์ชันสำหรับดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserSalaryByType(link.value))
.then((res) => {
const data = res.data.result;
@ -659,13 +643,24 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
/**
* งกนสำหรบเป dialog ประวการแกไข
* @param id id ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
http
.get(config.API.dataUserSalaryHistoryByType(link.value, idByRow.value))
.then((res) => {
@ -677,10 +672,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -691,11 +687,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none">
<span class="text-blue-6 text-weight-bold text-body1">{{
@ -732,17 +727,21 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<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"
:loading="isLoading"
:pagination="{ page: 1, rowsPerPage: 10 }"
>
<template v-slot:header="props">
<q-tr :props="props">
@ -766,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({
@ -851,6 +854,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="`ประวัติแก้ไข${salaryText}`"
@ -859,8 +863,10 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -1,10 +1,10 @@
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
@ -12,26 +12,27 @@ import type { NopaidFormType } from "@/modules/10_registry/interface/index/Main"
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const rows = ref<NopaidFormType[]>([]);
const rowsData = ref<NopaidFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<NopaidFormType[]>([]);
const rowsHistoryData = ref<NopaidFormType[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const dataPerson = useDataStore();
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
useCounterMixin();
const modalHistory = ref<boolean>(false);
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<NopaidFormType[]>([]); //
const rowsData = ref<NopaidFormType[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); //
const rowsHistory = ref<NopaidFormType[]>([]); //
const rowsHistoryData = ref<NopaidFormType[]>([]); //
const modalHistory = ref<boolean>(false); //
//
const salaryText = computed(() => {
return link.value == "" ? "เงินเดือน" : "ค่าจ้าง";
});
const visibleColumns = ref<string[]>([
"date",
"detail",
@ -41,7 +42,6 @@ const visibleColumns = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "date",
@ -128,7 +128,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"date",
"reference",
@ -138,7 +137,6 @@ const visibleColumnsHistory = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "date",
@ -221,18 +219,12 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const fileGroup = ref<string>(`เอกสารบันทึกวันที่ไม่ได้รับ${salaryText.value}`); //
const fileGroup = ref<string>(`เอกสารบันทึกวันที่ไม่ได้รับ${salaryText.value}`);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserNopaidByType(link.value))
.then((res) => {
const data = res.data.result;
@ -243,14 +235,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนสำหรบเปดประวการแกไข
* @param id รหสของแถวทกเลอกสำหรบประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(
config.API.dataUserSalaryNopaidHistoryByType(link.value, idByRow.value)
)
@ -263,15 +266,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบดาวนโหลดไฟล
* @param id รหสของแถวทกเลอกสำหรบดาวนโหลด
* @param profileId รหสโปรไฟลของผใช
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (e) {
messageError($q, e);
} finally {
hideLoader();
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูล */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -282,11 +298,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1">{{
@ -323,6 +338,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -334,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">
@ -448,6 +466,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,37 +1,34 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { CertificateDetail } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const dataPerson = useDataStore();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
useCounterMixin();
const idByRow = ref<string>("");
const rows = ref<CertificateDetail[]>([]);
const rowsData = ref<CertificateDetail[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<CertificateDetail[]>([]);
const rowsHistoryData = ref<CertificateDetail[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<CertificateDetail[]>([]); //
const rowsData = ref<CertificateDetail[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<CertificateDetail[]>([]); //
const rowsHistoryData = ref<CertificateDetail[]>([]); //
const modalHistory = ref<boolean>(false); /// modal
const visibleColumns = ref<string[]>([
"certificateType",
"issuer",
@ -126,7 +123,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"certificateType",
"issuer",
@ -218,18 +214,12 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const fileGroup = ref<string>("เอกสารใบอนุญาตประกอบวิชาชีพ"); //
const fileGroup = ref<string>("เอกสารใบอนุญาตประกอบวิชาชีพ");
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลใบอนุญาตประกอบวิชาชีพ */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserCertificateByType(link.value, "certificate"))
.then((res) => {
const data = res.data.result;
@ -240,14 +230,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนสำหรบเป modal แสดงประวการแกไขใบอนญาต
* @param id ID ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไขใบอนุญาต */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(
config.API.dataUserCertificateHistoryByType(
link.value,
@ -264,15 +265,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบดาวนโหลดไฟล
* @param id ID ของไฟลองการดาวนโหลด
* @param profileId ID ของโปรไฟล
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -283,11 +297,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none">
<span class="text-blue-6 text-weight-bold text-body1"
@ -324,6 +337,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -335,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">
@ -445,6 +461,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,34 +1,32 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useDataStore } from "@/stores/data";
import { useCounterMixin } from "@/stores/mixin";
import type { TrainingFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const rows = ref<TrainingFormType[]>([]);
const rowsData = ref<TrainingFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<TrainingFormType[]>([]);
const rowsHistoryData = ref<TrainingFormType[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const dataPerson = useDataStore();
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<TrainingFormType[]>([]); // /
const rowsData = ref<TrainingFormType[]>([]); // /
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<TrainingFormType[]>([]); // /
const rowsHistoryData = ref<TrainingFormType[]>([]); // /
const modalHistory = ref<boolean>(false); // / modal /
const visibleColumns = ref<string[]>([
"name", //
"topic", //
@ -187,7 +185,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"name", //
"topic", //
@ -343,15 +340,11 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserCertificateByType(link.value, "training"))
.then((res) => {
const data = res.data.result;
@ -362,14 +355,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* เป modal แสดงประวการแกไขการฝกอบรม/งาน
* @param id ID ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไขการฝึกอบรม/ดูงาน */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(
config.API.dataUserCertificateHistoryByType(
link.value,
@ -386,10 +390,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -400,11 +405,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -441,6 +445,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -452,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">
@ -517,6 +524,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขการฝึกอบรม/ดูงาน'"
@ -525,8 +533,10 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
@ -10,27 +10,25 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { InsigniaFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const rows = ref<InsigniaFormType[]>([]);
const rowsData = ref<InsigniaFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<InsigniaFormType[]>([]);
const rowsHistoryData = ref<InsigniaFormType[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const dataPerson = useDataStore();
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
useCounterMixin();
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const idByRow = ref<string>(""); // id
const rows = ref<InsigniaFormType[]>([]); //
const rowsData = ref<InsigniaFormType[]>([]); //
const filter = ref<string>(""); //
const rowsHistory = ref<InsigniaFormType[]>([]); //
const rowsHistoryData = ref<InsigniaFormType[]>([]); //
const modalHistory = ref<boolean>(false); // / modal
const visibleColumns = ref<String[]>([
"insignia",
"insigniaType",
@ -239,7 +237,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"insignia",
"insigniaType",
@ -433,18 +430,12 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const fileGroup = ref<string>("เครื่องราชฯ"); //
const fileGroup = ref<string>("เครื่องราชฯ");
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลเครื่องราชฯ */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserCertificateByType(link.value, "insignia"))
.then((res) => {
const data = res.data.result;
@ -455,14 +446,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนสำหรบเป modal ประวการแกไขเครองราชฯ
* @param id ID ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันสำหรับดึงข้อมูลประวัติการแก้ไขเครื่องราชฯ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(
config.API.dataUserCertificateHistoryByType(
link.value,
@ -479,15 +481,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบดาวนโหลดไฟล
* @param id ID ของไฟลองการดาวนโหลด
* @param profileId ID ของโปรไฟล
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -498,11 +513,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -539,6 +553,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -550,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">
@ -674,8 +691,10 @@ onMounted(async () => {
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:type="'insignia'"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -1,12 +1,11 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { HonorFormData } from "@/modules/10_registry/interface/index/Main";
@ -14,25 +13,23 @@ import type { HonorFormData } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const store = useRegistryInFormationStore();
const rows = ref<HonorFormData[]>([]);
const rowsData = ref<HonorFormData[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<HonorFormData[]>([]);
const rowsHistoryData = ref<HonorFormData[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const dataPerson = useDataStore();
const { getPathUploadFlie } = useRegistryDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
useCounterMixin();
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const rows = ref<HonorFormData[]>([]); //
const rowsData = ref<HonorFormData[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<HonorFormData[]>([]); //
const rowsHistoryData = ref<HonorFormData[]>([]); //
const modalHistory = ref<boolean>(false); // / modal
const visibleColumns = ref<String[]>([
"issuer",
"detail",
@ -127,7 +124,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"issuer",
"detail",
@ -219,18 +215,12 @@ const columnsHistory = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const fileGroup = ref<string>("ประกาศเกียรติคุณ"); //
const fileGroup = ref<string>("ประกาศเกียรติคุณ");
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันสำหรับดึงข้อมูลประกาศเกียรติคุณ */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserCertificateByType(link.value, "honor"))
.then((res) => {
const data = res.data.result;
@ -241,18 +231,30 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/**
* เป modal ประวการแกไข
* @param id ID ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get history */
function getHistory() {
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
const url =
dataPerson.officerType == "OFFICER"
? config.API.dataUserHonorHistory("honor", "", idByRow.value)
: config.API.dataUserHonorHistory("honor", "-employee", idByRow.value);
showLoader();
http
await http
.get(url)
.then((res) => {
const data = res.data.result;
@ -263,15 +265,28 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนสำหรบดาวนโหลดไฟล
* @param id ID ของไฟลองการดาวนโหลด
* @param profileId id ของโปรไฟล
*/
async function onDownloadFile(id: string, profileId: string) {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
showLoader();
try {
const data = await getPathUploadFlie(fileGroup.value, profileId, id);
window.open(data.downloadUrl, "_blank");
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
}
/** ฟังก์ชันสำหรับค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -282,11 +297,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
@ -323,6 +337,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -334,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">
@ -445,6 +462,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
@ -12,31 +12,27 @@ import type {
DataOption,
} from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const rows = ref<AssessmentsFormType[]>([]);
const rowsData = ref<AssessmentsFormType[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<AssessmentsFormType[]>([]);
const rowsHistoryData = ref<AssessmentsFormType[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const dataPerson = useDataStore();
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); //
const link = ref<string>(""); //
const rows = ref<AssessmentsFormType[]>([]); //
const rowsData = ref<AssessmentsFormType[]>([]); //
const filter = ref<string>(""); //
const idByRow = ref<string>(""); // id
const rowsHistory = ref<AssessmentsFormType[]>([]); //
const rowsHistoryData = ref<AssessmentsFormType[]>([]); //
const isLoading = ref<boolean>(false); //
const isLoadingHistory = ref<boolean>(false); //
const periodOp = ref<DataOption[]>([
{ id: "OCT", name: "ตุลาคม" },
{ id: "APR", name: "เมษายน" },
]);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const modalHistory = ref<boolean>(false); // modal
const columns = ref<QTableProps["columns"]>([
{
name: "date",
@ -328,7 +324,6 @@ const visibleColumnsHistory = ref<string[]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumns = ref<string[]>([
"point1Total",
"year",
@ -344,15 +339,10 @@ const visibleColumns = ref<string[]>([
"lastUpdatedAt",
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserCertificateByType(link.value, "assessments"))
.then((res) => {
const data = res.data.result;
@ -363,14 +353,25 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนเป modal ประวการแกไข
* @param id - id ของแถวทเลอก
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันดึงข้อมูลประวัติการแก้ไข */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(
config.API.dataUserCertificateHistoryByType(
link.value,
@ -387,10 +388,14 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/**
* งกนตรวจสอบชวงคะแนน
* @param val - าทองการตรวจสอบ
*/
function textRangePoint(val: number | undefined) {
if (val == undefined) val = -1;
if (val < 60.0) return "(คะแนนต่ำกว่าร้อยละ 60.00)";
@ -401,6 +406,10 @@ function textRangePoint(val: number | undefined) {
else return "";
}
/**
* งกนตรวจสอบคะแนน
* @param val - าทองการตรวจสอบ
*/
function textPoint(val: number | undefined) {
if (val == undefined) val = -1;
if (val < 60.0) return "ต้องปรับปรุง";
@ -440,6 +449,7 @@ onMounted(async () => {
v-model="filter"
label="ค้นหา"
style="max-width: 200px"
@keydown.enter.prevent="onSearch"
>
<template v-slot:append>
<q-icon name="search" />
@ -461,6 +471,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -472,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">
@ -545,6 +558,7 @@ onMounted(async () => {
</template>
</d-table>
</div>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขผลการประเมินการปฏิบัติราชการ'"
@ -553,8 +567,10 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -1,34 +1,27 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { ref, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import DialogDevelop from "@/modules/10_registry/Dialog/DialogDevelopmant.vue";
const typeIDP = ref<string>("");
const link = ref<string>("");
const dataPerson = useDataStore();
const idByRow = ref<string>("");
const rows = ref<any[]>([]);
const rowsData = ref<any[]>([]);
const filter = ref<string>("");
const rowsHistory = ref<any[]>([]);
const rowsHistoryData = ref<any[]>([]);
const $q = useQuasar();
const mode = ref<boolean>($q.screen.gt.xs);
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const modalDevelop = ref<boolean>(false);
const kpiDevelopmentId = ref<string>("");
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const dataPerson = useDataStore();
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const mode = ref<boolean>($q.screen.gt.xs); //
const typeIDP = ref<string>(""); //
const link = ref<string>(""); //
const isLoading = ref<boolean>(false); //
const rows = ref<any[]>([]); //
const rowsData = ref<any[]>([]); //
const filter = ref<string>(""); //
const modalDevelop = ref<boolean>(false); // / Dialog
const kpiDevelopmentId = ref<string>(""); // ID
const visibleColumns = ref<string[]>([
"no",
"name",
@ -39,7 +32,6 @@ const visibleColumns = ref<string[]>([
"lastUpdateFullName",
"lastUpdatedAt",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -130,21 +122,15 @@ const columns = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const paginationPlan = ref({
page: 1,
rowsPerPage: 10,
});
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.developmentUserByType(link.value))
.then((res) => {
const data = res.data.result;
@ -155,31 +141,7 @@ function getData() {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
/** get history */
function getHistory() {
showLoader();
http
.get(
config.API.dataUserCertificateHistoryByType(
link.value,
"assessments",
idByRow.value
)
)
.then((res) => {
const data = res.data.result;
rowsHistory.value = data;
rowsHistoryData.value = data;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
@ -193,6 +155,7 @@ function openDialogDevelop(data: any) {
typeIDP.value = data.type;
}
/** ฟังก์ชันค้นหาข้อมูล */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -203,12 +166,13 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12" v-if="dataPerson.officerType == 'OFFICER'">
<!-- v-if="dataPerson.officerType == 'OFFICER'" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1"
>การพฒนารายบคคล (Individual Development Plan)</span
@ -244,6 +208,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -255,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">

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { useQuasar, type QTableProps } from "quasar";
import { is, useQuasar, type QTableProps } from "quasar";
import { ref, onMounted } from "vue";
import http from "@/plugins/http";
@ -9,16 +9,15 @@ import { useDataStore } from "@/stores/data";
import type { OtherFormType } from "@/modules/10_registry/interface/index/Main";
//history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
const link = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const dataPerson = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
mixin;
const { messageError, date2Thai, onSearchDataTable } = useCounterMixin();
const link = ref<string>("");
const isLoading = ref<boolean>(false);
const isLoadingHistory = ref<boolean>(false);
const idByRow = ref<string>("");
const rows = ref<OtherFormType[]>([]);
const rowsData = ref<OtherFormType[]>([]);
@ -26,10 +25,7 @@ const filter = ref<string>("");
const rowsHistory = ref<OtherFormType[]>([]);
const rowsHistoryData = ref<OtherFormType[]>([]);
const mode = ref<boolean>($q.screen.gt.xs);
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const visibleColumns = ref<string[]>([
"date",
"detail",
@ -85,7 +81,6 @@ const columns = ref<QTableProps["columns"]>([
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const visibleColumnsHistory = ref<string[]>([
"date",
"detail",
@ -139,15 +134,10 @@ const columnsHistory = ref<QTableProps["columns"]>([
},
]);
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูล */
async function getData() {
isLoading.value = true;
await http
.get(config.API.dataUserOtherByType(link.value))
.then((res) => {
const data = res.data.result;
@ -156,14 +146,27 @@ function getData() {
})
.catch((e) => {
messageError($q, e);
hideLoader();
})
.finally(() => {
isLoading.value = false;
});
}
/** get history */
function getHistory() {
showLoader();
http
/**
* งกนเปดโมดลดประว
* @param id ID ของแถวทองการดประว
*/
function onHistory(id: string) {
modalHistory.value = true;
idByRow.value = id;
}
/** ฟังก์ชันดึงประวัติการแก้ไขข้อมูลอื่นๆ */
async function getHistory() {
isLoadingHistory.value = true;
rowsHistory.value = [];
rowsHistoryData.value = [];
await http
.get(config.API.dataUserOtherHistoryByType(link.value, idByRow.value))
.then((res) => {
const data = res.data.result;
@ -174,10 +177,11 @@ function getHistory() {
messageError($q, e);
})
.finally(() => {
hideLoader();
isLoadingHistory.value = false;
});
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
@ -188,11 +192,10 @@ function onSearch() {
onMounted(async () => {
link.value = await dataPerson.getProFileType();
getData();
await getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none">
<span class="text-blue-6 text-weight-bold text-body1">อมลอนๆ</span>
@ -227,6 +230,7 @@ onMounted(async () => {
:display-value="$q.lang.table.columns"
/>
</q-toolbar>
<d-table
flat
dense
@ -238,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">
@ -269,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>
@ -301,15 +308,9 @@ 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>
<DialogHistory
v-model:modal="modalHistory"
:title="'ประวัติแก้ไขข้อมูลอื่นๆ'"
@ -318,6 +319,7 @@ onMounted(async () => {
:rows-data="rowsHistoryData"
:visibleColumns="visibleColumnsHistory"
:columns="columnsHistory"
:is-loading="isLoadingHistory"
/>
</template>
<style scoped>

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar, type QTableProps } from "quasar";
import { ref, reactive, onMounted } from "vue";
import { is, useQuasar } from "quasar";
import { ref, onMounted } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
@ -9,23 +9,17 @@ import { useRegistryInFormationStore } from "@/modules/10_registry/store/registr
import type { FileFormType } from "@/modules/10_registry/interface/index/Main";
const fileList = ref<FileFormType[]>([]);
const store = useRegistryInFormationStore();
const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const store = useRegistryInFormationStore();
const { showLoader, hideLoader, messageError } = useCounterMixin();
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const isLoading = ref<boolean>(false);
const fileList = ref<FileFormType[]>([]);
function onHistory() {
modalHistory.value = true;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูลไฟล์ */
async function getData() {
isLoading.value = true;
await http
.get(
config.API.fileByFileUser(
"ระบบทะเบียนประวัติ",
@ -41,9 +35,7 @@ function getData() {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 1500);
isLoading.value = false;
});
}
@ -51,9 +43,9 @@ function getData() {
* ดาวนโหลดลงคไฟล
* @param fileName file name
*/
function downloadFile(fileName: string) {
async function downloadFile(fileName: string) {
showLoader();
http
await http
.get(
config.API.fileByFile(
"ระบบทะเบียนประวัติ",
@ -69,7 +61,7 @@ function downloadFile(fileName: string) {
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
.finally(() => {
hideLoader();
});
}
@ -78,8 +70,8 @@ onMounted(() => {
getData();
});
</script>
<template>
<!-- v-if="mode" -->
<div class="col-12">
<q-toolbar class="q-px-none q-mt-md">
<span class="text-blue-6 text-weight-bold text-body1">เอกสารหลกฐาน</span>
@ -89,7 +81,12 @@ onMounted(() => {
ไฟลเอกสารหลกฐาน
</div>
<div class="col-12"><q-separator /></div>
<div class="row col-12 q-col-gutter-y-sm q-pa-sm">
<div v-if="isLoading" class="col-12 q-pa-sm">
<q-skeleton type="QSlider" />
</div>
<div v-else class="row col-12 q-col-gutter-y-sm q-pa-sm">
<div v-if="fileList.length > 0" class="col-xs-12 row">
<q-list class="full-width rounded-borders" bordered separator>
<q-item
@ -124,6 +121,7 @@ onMounted(() => {
</q-card>
</div>
</template>
<style scoped>
.absolute_button {
position: absolute;

View file

@ -9,23 +9,17 @@ import { useRegistryInFormationStore } from "@/modules/10_registry/store/registr
import type { FileFormType } from "@/modules/10_registry/interface/index/Main";
const fileList = ref<FileFormType[]>([]);
const store = useRegistryInFormationStore();
const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const store = useRegistryInFormationStore();
const { showLoader, hideLoader, messageError } = useCounterMixin();
const modalHistory = ref<boolean>(false);
/** ตัวแปรข้อมูล */
const isLoading = ref<boolean>(false);
const fileList = ref<FileFormType[]>([]);
function onHistory() {
modalHistory.value = true;
}
/** get data */
function getData() {
showLoader();
http
/** ฟังก์ชันดึงข้อมูลไฟล์ */
async function getData() {
isLoading.value = true;
await http
.get(
config.API.fileByFileUser(
"ระบบทะเบียนประวัติ",
@ -41,9 +35,7 @@ function getData() {
messageError($q, e);
})
.finally(() => {
setTimeout(() => {
hideLoader();
}, 1500);
isLoading.value = false;
});
}
@ -51,9 +43,9 @@ function getData() {
* ดาวนโหลดลงคไฟล
* @param fileName file name
*/
function downloadFile(fileName: string) {
async function downloadFile(fileName: string) {
showLoader();
http
await http
.get(
config.API.fileByFile(
"ระบบทะเบียนประวัติ",
@ -69,7 +61,7 @@ function downloadFile(fileName: string) {
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
.finally(() => {
hideLoader();
});
}
@ -89,7 +81,11 @@ onMounted(() => {
ไฟลเอกสาร ..7
</div>
<div class="col-12"><q-separator /></div>
<div class="row col-12 q-col-gutter-y-sm q-pa-sm">
<div v-if="isLoading" class="col-12 q-pa-sm">
<q-skeleton type="QSlider" />
</div>
<div v-else class="row col-12 q-col-gutter-y-sm q-pa-sm">
<div v-if="fileList.length > 0" class="col-xs-12 row">
<q-list class="full-width rounded-borders" bordered separator>
<q-item

View file

@ -1,35 +1,47 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import DialogHeader from "@/components/DialogHeader.vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
const type = ref<string>("");
const mixin = useCounterMixin();
const { date2Thai, onSearchDataTable, findOrgNameHtml } = mixin;
const modal = defineModel<boolean>("modal", { required: true });
const title = defineModel<string>("title", { required: true });
/** import type */
import type { QTableProps } from "quasar";
const filter = ref<string>("");
/** import component */
import DialogHeader from "@/components/DialogHeader.vue";
const rows = defineModel<any>("rows");
const rowsData = defineModel<any>("rowsData");
const columns = defineModel<QTableProps["columns"]>("columns");
const visibleColumns = defineModel<string[]>("visibleColumns");
const { date2Thai, onSearchDataTable, findOrgNameHtml } = useCounterMixin();
/** define model */
const modal = defineModel<boolean>("modal", { required: true }); // modal visibility
const isLoading = defineModel<boolean>("isLoading", { required: true }); // loading state
const title = defineModel<string>("title", { required: true }); // dialog title
const rows = defineModel<any[]>("rows"); // data rows for the table
const rowsData = defineModel<any[]>("rowsData"); // raw data for the table
const columns = defineModel<QTableProps["columns"]>("columns"); // table columns definition
const visibleColumns = defineModel<string[]>("visibleColumns"); // visible columns in the table
/** define props */
const props = defineProps({
getData: Function, // function to fetch data
type: String, // type of data (e.g., "Leave", "insignia")
});
const type = ref<string>(""); //
const filter = ref<string>(""); // filter input for searching
const pagination = ref({
sortBy: "lastUpdatedAt",
});
const props = defineProps({
getData: Function,
type: String,
});
/** ปิด Dialog และรีเซ็ตค่า */
function close() {
modal.value = false;
filter.value = "";
}
/**
* งกนแปลงวนทเปนรปแบบไทย
* @param val - date range value
*/
function dateThaiRange(val: [Date, Date]) {
if (val === null) {
} else if (date2Thai(val[0]) === date2Thai(val[1])) {
@ -39,6 +51,10 @@ function dateThaiRange(val: [Date, Date]) {
}
}
/**
* งกนแปลงสถานะการลาเปนขอความท
* @param val สถานะการลา
*/
function statusLeave(val: string) {
switch (val) {
case "waitting":
@ -54,10 +70,11 @@ function statusLeave(val: string) {
}
}
/** ฟังก์ชันค้นหาข้อมูลในตาราง */
function onSearch() {
rows.value = onSearchDataTable(
filter.value,
rowsData.value,
rowsData.value ? rowsData.value : [],
columns.value ? columns.value : []
);
}
@ -112,140 +129,139 @@ watch(
</div>
</div>
<d-table
flat
dense
bordered
virtual-scroll
:rows="rows"
:columns="columns"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<div class="col-12">
<d-table
flat
dense
bordered
virtual-scroll
:rows="rows"
:columns="columns"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48"
:pagination="pagination"
:loading="isLoading"
row-key="id"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="(col, index) in props.cols" :key="col.name">
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else-if="col.name == 'insignia' && type == 'insignia'">
{{ props.row.insignia ? `${props.row.insignia.name} ` : "-"
}}{{
props.row.insignia.shortName
? `(${props.row.insignia.shortName})`
: ""
}}
</div>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="(col, index) in props.cols" :key="col.name">
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else-if="col.name == 'insignia' && type == 'insignia'">
{{ props.row.insignia ? `${props.row.insignia.name} ` : "-"
}}{{
props.row.insignia.shortName
? `(${props.row.insignia.shortName})`
: ""
}}
</div>
<div v-else-if="col.name == 'dateLeave' && type == 'Leave'">
{{
dateThaiRange([
props.row.dateStartLeave,
props.row.dateEndLeave,
])
}}
</div>
<div v-else-if="col.name == 'status' && type == 'Leave'">
{{ props.row.status ? statusLeave(props.row.status) : "-" }}
</div>
<div v-else-if="col.name == 'organization'">
{{
props.row
? findOrgNameHtml({
root: props.row.orgRoot,
child1: props.row.orgChild1,
child2: props.row.orgChild2,
child3: props.row.orgChild3,
child4: props.row.orgChild4,
})
: "-"
}}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
<template v-slot:item="props">
<div
class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3 grid-style-transition"
>
<q-card bordered flat class="q-pt-md">
<q-list dense>
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section class="fix_top">
<q-item-label class="text-grey-6 text-weight-medium">{{
col.label
}}</q-item-label>
</q-item-section>
<q-item-section
v-if="col.name == 'insignia' && type == 'insignia'"
class="fix_top"
>
<q-item-label class="text-dark text-weight-medium">
{{
props.row.insignia
? `${props.row.insignia.name} `
: "-"
}}{{
props.row.insignia.shortName
? `(${props.row.insignia.shortName})`
: ""
}}</q-item-label
<div v-else-if="col.name == 'dateLeave' && type == 'Leave'">
{{
dateThaiRange([
props.row.dateStartLeave,
props.row.dateEndLeave,
])
}}
</div>
<div v-else-if="col.name == 'status' && type == 'Leave'">
{{ props.row.status ? statusLeave(props.row.status) : "-" }}
</div>
<div v-else-if="col.name == 'organization'">
{{
props.row
? findOrgNameHtml({
root: props.row.orgRoot,
child1: props.row.orgChild1,
child2: props.row.orgChild2,
child3: props.row.orgChild3,
child4: props.row.orgChild4,
})
: "-"
}}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
<template v-slot:item="props">
<div
class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3 grid-style-transition"
>
<q-card bordered flat class="q-pt-md">
<q-list dense>
<q-item v-for="col in props.cols" :key="col.name">
<q-item-section class="fix_top">
<q-item-label class="text-grey-6 text-weight-medium">{{
col.label
}}</q-item-label>
</q-item-section>
<q-item-section
v-if="col.name == 'insignia' && type == 'insignia'"
class="fix_top"
>
</q-item-section>
<q-item-section
v-else-if="col.name == 'dateLeave' && type == 'Leave'"
class="fix_top"
>
<q-item-label class="text-dark text-weight-medium">
{{
dateThaiRange([
props.row.dateStartLeave,
props.row.dateEndLeave,
])
}}</q-item-label
<q-item-label class="text-dark text-weight-medium">
{{
props.row.insignia
? `${props.row.insignia.name} `
: "-"
}}{{
props.row.insignia.shortName
? `(${props.row.insignia.shortName})`
: ""
}}</q-item-label
>
</q-item-section>
<q-item-section
v-else-if="col.name == 'dateLeave' && type == 'Leave'"
class="fix_top"
>
</q-item-section>
<q-item-section
v-else-if="col.name == 'status' && type == 'Leave'"
class="fix_top"
>
<q-item-label class="text-dark text-weight-medium">
{{
props.row.status ? statusLeave(props.row.status) : "-"
}}</q-item-label
<q-item-label class="text-dark text-weight-medium">
{{
dateThaiRange([
props.row.dateStartLeave,
props.row.dateEndLeave,
])
}}</q-item-label
>
</q-item-section>
<q-item-section
v-else-if="col.name == 'status' && type == 'Leave'"
class="fix_top"
>
</q-item-section>
<q-item-section v-else class="fix_top">
<q-item-label class="text-dark text-weight-medium">{{
col.value ? col.value : "-"
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</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>
<q-item-label class="text-dark text-weight-medium">
{{
props.row.status
? statusLeave(props.row.status)
: "-"
}}</q-item-label
>
</q-item-section>
<q-item-section v-else class="fix_top">
<q-item-label class="text-dark text-weight-medium">{{
col.value ? col.value : "-"
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</template>
</d-table>
</div>
</q-card-section>
</q-card>
</q-dialog>

View file

@ -12,9 +12,7 @@ import DialogHeader from "@/components/DialogHeader.vue";
import { useRequestEditStore } from "@/modules/10_registry/store/RequestEdit";
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
/** use*/
const $q = useQuasar();
const link = ref<string>("");
const store = useRequestEditStore();
@ -22,24 +20,23 @@ const dataStore = useDataStore();
const { dialogConfirm, showLoader, hideLoader, messageError, success } =
useCounterMixin();
/**
* props
*/
/** props*/
const modalInfo = ref<boolean>(false);
const modal = defineModel<boolean>("modal", { required: true });
const props = defineProps({
fetchData: { type: Function, requied: true },
fetchData: { type: Function, required: true },
});
const isReadOnly = ref<boolean>(false);
const profileId = ref<string>("");
const isReadOnly = ref<boolean>(false); //
const profileId = ref<string>(""); // profileId q
const formData = reactive({
topic: "",
detail: "",
document: null,
});
const topicOption = ref<string[]>(store.optionTopic);
const topicOption = ref<string[]>(store.optionTopic); //
/** function ปิด Dialog และเคลียร์ข้อมูล */
function closeDialog() {
modal.value = false;
formData.topic = "";
@ -47,9 +44,7 @@ function closeDialog() {
formData.document = null;
}
/**
* function นยนการยนคำรองขอแกไขขอม
*/
/** function ยืนยันการยื่นคำร้องขอแก้ไขข้อมูล */
function onSubmit() {
dialogConfirm(
$q,
@ -65,17 +60,18 @@ function onSubmit() {
})
.then(async (res) => {
if (formData.document) {
createURLUpload(res.data.result, formData.document);
await createURLUpload(res.data.result, formData.document);
} else {
formData.document = null;
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
closeDialog();
hideLoader();
}
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
},
@ -86,10 +82,12 @@ function onSubmit() {
/**
* function สราง URL ปโหลไฟลเอกสารหลกฐาน
* @param id คำรองขอแกไขขอม
* @param file ไฟลปโหลด
*/
function createURLUpload(id: string, file: any) {
async function createURLUpload(id: string, file: any) {
const fileName = { fileName: file.name };
http
await http
.post(
config.API.file(
"ระบบทะเบียนประวัติ",
@ -108,7 +106,7 @@ function createURLUpload(id: string, file: any) {
res.data[key]?.fileName !== ""
);
foundKey &&
uploadFileDoc(res.data[foundKey]?.uploadUrl, formData.document);
(await uploadFileDoc(res.data[foundKey]?.uploadUrl, formData.document));
})
.catch((err) => {
messageError($q, err);
@ -117,32 +115,29 @@ function createURLUpload(id: string, file: any) {
/**
* function สำหรบอพโหลดไฟลเอกสารหลกฐาน
* @param uploadUrl URL สำหรบอปโหลดไฟล
* @param file ไฟลปโหลด
*/
function uploadFileDoc(uploadUrl: string, file: any) {
showLoader();
axios
async function uploadFileDoc(uploadUrl: string, file: any) {
await axios
.put(uploadUrl, file, {
headers: {
"Content-Type": file.type,
},
})
.then(async (res) => {
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
closeDialog();
})
.catch((e) => {
messageError($q, e);
hideLoader();
})
.finally(() => {
hideLoader();
});
}
/**
* class input
* @param val
* function สำหรบจดการ class ของ input
* @param val าทใชในการกำหนด class
*/
function classInput(val: boolean) {
return {
@ -164,9 +159,7 @@ function filterOption(val: string, update: Function) {
});
}
/**
* function fetch profileId
*/
/** function fetch profileId */
async function fetchProfile() {
try {
isReadOnly.value = dataStore.officerType === "OFFICER";

View file

@ -0,0 +1,40 @@
<template>
<div class="col-12 col-sm-12 col-md-6 q-gutter-y-sm">
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">
อยตามทะเบยนบาน
</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">งหว</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">เขต / อำเภอ</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">แขวง / ตำบล</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
<div class="row">
<div class="col-5 text-grey-6 text-weight-medium">รหสไปรษณ</div>
<div class="col-7">
<q-skeleton type="text" />
</div>
</div>
</div>
</template>

Some files were not shown because too many files have changed in this diff Show more