fix loading Skeleton

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-08-05 15:15:49 +07:00
parent ff6101067e
commit 016132096e
63 changed files with 3468 additions and 3452 deletions

View file

@ -1,44 +1,51 @@
<script setup lang="ts">
import { ref, computed } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
import genReport from "@/plugins/genreport";
import { ref, computed, onMounted } from "vue";
import { useQuasar } from "quasar";
//
import http from "@/plugins/http";
import config from "@/app.config";
import genReport from "@/plugins/genreport";
import { useRouter } from "vue-router";
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
import { useDataStore } from "@/stores/data";
import { useCounterMixin } from "@/stores/mixin";
/** import components */
import InformationPage from "@/modules/10_registry/tabs/01_information.vue";
import GovernmentPage from "@/modules/10_registry/tabs/02_government.vue";
import SalaryPage from "@/modules/10_registry/tabs/03_salary.vue";
import Certificate from "@/modules/10_registry/tabs/04_Achievement.vue";
import OtherPage from "@/modules/10_registry/tabs/05_other.vue";
import { useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
import { useQuasar } from "quasar";
const store = useRegistryInFormationStore();
const $q = useQuasar();
const dataStore = useDataStore();
const mixin = useCounterMixin();
const { messageError, showLoader, hideLoader } = mixin;
const router = useRouter();
const tab = ref<string>("information");
const store = useRegistryInFormationStore();
const dataStore = useDataStore();
const { messageError, showLoader, hideLoader } = useCounterMixin();
const tab = ref<string>("information"); //
const sizeImg = ref<string>(""); //
/** ข้อความแสดงชื่อเงินเดือนหรือค่าจ้าง */
const salaryText = computed(() => {
return dataStore.officerType == "OFFICER" ? "เงินเดือน" : "ค่าจ้าง";
return dataStore.officerType == "OFFICER" ? "เงินเดือน" : "ค่าจ้าง";
});
const sizeImg = ref<string>("");
function onResize(size: any) {
/**
* งกนจดการขนาดของรปภาพโปรไฟล
* @param size ขนาดทไดจาก q-resize-observer
*/
function onResize(size: { width: number; height: number }) {
const width = size.width > 100 ? 100 : size.width;
sizeImg.value = `${width}px`;
}
function onMobile(type: string) {
router.push(`/registry/${type}`);
}
/**
* งกนดาวนโหลดไฟล ..7/..1 หรอประวแบบย
* @param type ประเภทไฟลองการดาวนโหลด
* FULL: ..7/..1
* SHORT: ประวแบบย
*/
async function onClickDownloadKp7(type: string) {
showLoader();
const url =
@ -66,19 +73,19 @@ async function onClickDownloadKp7(type: string) {
});
}
/**
* งชนกลบหนาหล
*/
/** ฟังชั่นกลับหน้าหลัก*/
const clickBack = () => {
router.push(`/`);
};
/**
* function redirect ไปหนารายการคำรองขอแกไขขอม
*/
/** ฟังก์ชัน redirect ไปหน้ารายการคำร้องขอแก้ไขข้อมูล*/
function redirectToPagePetition() {
router.push(`/registry/request-edit`);
}
function onMobile(type: string) {
router.push(`/registry/${type}`);
}
</script>
<template>
@ -106,7 +113,40 @@ function redirectToPagePetition() {
</div>
<div v-if="$q.screen.gt.xs" class="row q-col-gutter-md">
<div class="col-3">
<q-card bordered>
<q-card v-if="dataStore.isLoadingProfile" bordered>
<q-resize-observer @resize="onResize" />
<q-card-section>
<div class="relative-position" style="height: 120px">
<div class="absolute-center">
<q-skeleton type="QAvatar" :size="sizeImg || '100px'" />
</div>
</div>
<div class="column items-center q-mt-md q-mb-sm q-gutter-sm">
<q-skeleton type="text" width="120px" />
<q-skeleton type="text" width="150px" />
<q-skeleton type="text" width="100px" />
<q-skeleton type="text" width="50px" />
</div>
</q-card-section>
<q-list separator class="q-mt-md">
<q-item v-for="i in 2" :key="i">
<q-item-section>
<q-skeleton type="text" />
</q-item-section>
<q-item-section>
<q-skeleton type="text" />
</q-item-section>
</q-item>
</q-list>
<q-card-section class="q-gutter-y-sm">
<q-skeleton type="QBtn" class="full-width" height="48px" />
<q-skeleton type="QBtn" class="full-width" height="48px" />
</q-card-section>
</q-card>
<q-card v-else bordered>
<q-resize-observer @resize="onResize" />
<q-card-section>
<div class="relative-position" style="height: 120px">
@ -220,8 +260,6 @@ function redirectToPagePetition() {
<q-separator />
<!-- รายการเเตละหน -->
<q-tab-panels v-model="tab" animated>
<q-tab-panel name="information">
<InformationPage />
@ -248,7 +286,41 @@ function redirectToPagePetition() {
</div>
<div v-else>
<q-card bordered>
<q-card v-if="dataStore.isLoadingProfile" bordered>
<q-resize-observer @resize="onResize" />
<q-card-section>
<div class="relative-position" style="height: 120px">
<div class="absolute-center">
<q-skeleton type="QAvatar" :size="sizeImg || '100px'" />
</div>
</div>
<div class="column items-center q-mt-md q-mb-lg q-gutter-sm">
<q-skeleton type="text" width="120px" />
<q-skeleton type="text" width="150px" />
<q-skeleton type="text" width="100px" />
<q-skeleton type="text" width="50px" />
</div>
<div class="row justify-center q-gutter-x-lg">
<q-skeleton type="QRadio" size="48px" />
<q-skeleton type="QRadio" size="48px" />
</div>
<q-list separator class="q-mt-md">
<q-item v-for="i in 5" :key="i">
<q-item-section>
<q-skeleton type="text" width="120px" height="16px" />
</q-item-section>
<q-item-section avatar>
<q-skeleton type="QIcon" size="24px" />
</q-item-section>
</q-item>
</q-list>
</q-card-section>
</q-card>
<q-card v-else bordered>
<q-resize-observer @resize="onResize" />
<q-card-section>
<div class="text-center q-mt-md">

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { useRouter, useRoute } from "vue-router";
@ -37,8 +37,11 @@ const statusOptionMain = ref<DataOption[]>(
);
const statusOption = ref<DataOption[]>(statusOptionMain.value); //
const isLoading = ref<boolean>(false); //
async function fetchData() {
showLoader();
// showLoader();
isLoading.value = true;
await http
.get(config.API.requestEditByType(link.value) + `${requestId.value}`)
.then(async (res) => {
@ -56,9 +59,10 @@ async function fetchData() {
})
.catch((err) => {
messageError($q, err);
hideLoader();
})
.finally(() => {});
.finally(() => {
isLoading.value = false;
});
}
const checkFile = ref<null | false | "img" | "doc">(null); // null , false , "img" , "doc"
@ -154,7 +158,37 @@ onMounted(async () => {
</div>
</div>
<div class="col-12"><q-separator /></div>
<q-card-section class="col-12">
<q-card-section v-if="isLoading" class="col-12">
<div class="row q-col-gutter-sm">
<!-- นทนขอ Skeleton -->
<div class="col-md-2 col-xs-12">
<q-skeleton type="QInput" height="40px" />
</div>
<!-- เรอง Skeleton -->
<div class="col-md-10 col-xs-12">
<q-skeleton type="QInput" height="40px" />
</div>
<!-- รายละเอยด Skeleton -->
<div class="col-12">
<q-skeleton type="QInput" height="160px" />
</div>
<!-- ไฟล Skeleton -->
<div class="col-12 q-mt-md">
<q-skeleton
type="rect"
width="120px"
height="20px"
class="q-mb-sm"
/>
</div>
</div>
</q-card-section>
<q-card-section v-else class="col-12">
<div class="row q-col-gutter-sm">
<!-- นทนขอ -->
<div class="col-md-2 col-xs-12">
@ -265,7 +299,19 @@ onMounted(async () => {
<div class="q-pl-sm text-weight-bold text-dark">สถานะคำรอง</div>
</div>
<div class="col-12"><q-separator /></div>
<q-card-section class="col-12">
<q-card-section v-if="isLoading" class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-skeleton type="QInput" height="40px" />
</div>
<div class="col-12">
<q-skeleton type="QInput" height="160px" />
</div>
</div>
</q-card-section>
<q-card-section v-else class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-xs-12 col-md-12">
<q-select
@ -312,6 +358,7 @@ onMounted(async () => {
<div class="col-12 q-mt-sm">
<Workflow
v-if="dataStore.officerType && requestId"
ref="workflowRef"
:id="requestId"
:sys-name="

View file

@ -6,10 +6,10 @@ import http from "@/plugins/http";
import { useDataStore } from "@/stores/data";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import { useRequestEditStore } from "@/modules/10_registry/store/RequestEdit";
import { useCounterMixin } from "@/stores/mixin";
/**
* importType
*/
/**importType*/
import type { QTableProps } from "quasar";
import type {
DataOption,
@ -17,39 +17,26 @@ import type {
} from "@/modules/10_registry/interface/index/Main";
import type { DataRequest } from "@/modules/10_registry/interface/response/Main";
/**
* importComponents
*/
/** importComponents*/
import DialogAddRequestEdit from "@/modules/10_registry/components/DialogAddRequestEdit.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
/**
* importStore
*/
import { useRequestEditStore } from "@/modules/10_registry/store/RequestEdit";
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
/** use */
const $q = useQuasar();
const store = useRequestEditStore();
const link = ref<string>("");
const router = useRouter();
const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, dialogRemove, success } =
useCounterMixin();
const { messageError } = useCounterMixin();
/**
* วแปร
*/
/** ตัวแปร*/
const modalPetiton = ref<boolean>(false);
const status = ref<string>("");
const keyword = ref<string>("");
const statusOption = ref<DataOption[]>(store.optionStatus);
const isLoading = ref<boolean>(false);
/**
* Table
*/
/** Table*/
const rows = ref<DataRequest[]>([]);
const page = ref<number>(1);
const pageSize = ref<number>(10);
@ -124,32 +111,26 @@ const visibleColumns = ref<string[]>([
"remark",
]);
/**
* function กลบไปหนาทะเบยนประว
*/
/** function กลับไปหน้าทะเบียนประวัติ*/
function onclickBackPage() {
router.push(`/registry`);
}
/**
* function กดเพมรายการยนคำรองขอแกไขขอม
*/
/** function กดเพิ่มรายการยื่นคำร้องขอแก้ไขข้อมูล*/
function onClickAdd() {
modalPetiton.value = true;
}
/**
* function fetch รายการขอมลการยนคำรองขอแกไขขอม
*/
function fetchListRequset() {
/** function fetch รายการข้อมูลการยื่นคำร้องขอแก้ไขข้อมูล*/
async function fetchListRequset() {
let queryParams = {
page: page.value,
pageSize: pageSize.value,
status: status.value,
keyword: keyword.value,
};
showLoader();
http
isLoading.value = true;
await http
.get(config.API.requestEditByType(link.value) + `user`, {
params: queryParams,
})
@ -163,21 +144,17 @@ function fetchListRequset() {
messageError($q, err);
})
.finally(() => {
hideLoader();
isLoading.value = false;
});
}
/**
* function เลอกสถานะคำรอง
*/
/** function เลือกสถานะคำร้อง*/
function updateStatusValue() {
page.value = 1;
fetchListRequset();
}
/**
* function เคลยรอมลสถานะคำรอง
*/
/** function เคลียร์ข้อมูลสถานะคำร้อง*/
function clearStatus() {
status.value = "";
statusOption.value = store.optionStatus;
@ -197,80 +174,15 @@ function filterOption(val: string, update: Function) {
});
}
/**
* function พเดทขนาดหนาใน pagination
* @param newPagination อมลใหมของ pagination
*/
function updatePageSizePagination(newPagination: NewPagination) {
page.value = 1;
pageSize.value = newPagination.rowsPerPage;
}
/**
* function หาชอไฟล
* @param id รายการยนคำรองขอแกไขขอม
*/
function onDownloadFile(id: string) {
showLoader();
http
.get(
config.API.file(
"ระบบทะเบียนประวัติ",
"เอกสารหลักฐานคำร้องขอแก้ไขข้อมูล",
id
)
)
.then((res) => {
if (res.data.length !== 0) {
downloadUrl(id, res.data[0].fileName);
} else {
hideLoader();
}
})
.catch((e) => {
messageError($q, e);
hideLoader();
});
}
/**
* function โหลดไฟล
* @param id รายการยนคำรองขอแกไขขอม
* @param fileName อไฟล
*/
function downloadUrl(id: string, fileName: string) {
http
.get(
config.API.fileByFile(
"ระบบทะเบียนประวัติ",
"เอกสารหลักฐานคำร้องขอแก้ไขข้อมูล",
id,
fileName
)
)
.then((res) => {
window.open(res.data.downloadUrl, "_blank");
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
// function onDeleteLidt(id: string) {
// dialogRemove($q, () => {
// showLoader();
// http
// .delete(config.API.requestEdit + `${id}`)
// .then(async (res) => {
// await fetchListRequset();
// await success($q, "");
// })
// .catch((err) => {
// messageError($q, err);
// hideLoader();
// });
// });
// }
watch(
() => pageSize.value,
() => {
@ -381,7 +293,9 @@ onMounted(async () => {
</div>
</div>
<div class="col-12">
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table
v-else
:columns="columns"
:rows="rows"
row-key="id"
@ -411,36 +325,11 @@ onMounted(async () => {
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<!-- <div v-else-if="col.name === 'document'">
<q-btn
icon="mdi-download"
round
dense
flat
color="primary"
size="12px"
@click.stop.pervent="onDownloadFile(props.row.id)"
>
<q-tooltip>หลกฐานอางอ</q-tooltip>
</q-btn>
</div> -->
<div v-else class="table_ellipsis2">
{{ col.value ? col.value : "-" }}
</div>
</q-td>
<!-- <q-td>
<q-btn
v-if="props.row.status === 'PENDING'"
flat
round
color="red"
icon="mdi-delete"
size="12px"
@click="onDeleteLidt(props.row.id)"
>
<q-tooltip>ลบคำรองขอแกไขขอม</q-tooltip>
</q-btn>
</q-td> -->
</q-tr>
</template>
<template v-slot:pagination="scope">