ปรับ กล่องข้อความ
This commit is contained in:
parent
6c4c8df2f1
commit
4dab304a75
5 changed files with 529 additions and 196 deletions
138
src/components/PopupDetailInbox.vue
Normal file
138
src/components/PopupDetailInbox.vue
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from "vue";
|
||||||
|
|
||||||
|
import PopupReplyInbox from "@/components/PopupReplyInbox.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modal: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
clickClose: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modal"]);
|
||||||
|
|
||||||
|
const modal = ref<boolean>(false);
|
||||||
|
const detail = reactive<any>({
|
||||||
|
no: "",
|
||||||
|
body: "",
|
||||||
|
ratingModel: 0,
|
||||||
|
receiveDate: "",
|
||||||
|
sender: "",
|
||||||
|
subject: "",
|
||||||
|
payload: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modal,
|
||||||
|
() => {
|
||||||
|
if (props.modal) {
|
||||||
|
const data = props.data;
|
||||||
|
if (data) {
|
||||||
|
detail.no = data.no;
|
||||||
|
detail.body = data.body;
|
||||||
|
detail.ratingMode = data.ratingMode;
|
||||||
|
detail.receiveDate = data.receiveDate;
|
||||||
|
detail.sender = data.sender;
|
||||||
|
detail.subject = data.subject;
|
||||||
|
detail.payload = data.payload;
|
||||||
|
modal.value = props.modal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => modal.value,
|
||||||
|
() => {
|
||||||
|
if (!modal.value) {
|
||||||
|
emit("update:modal", modal.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const modalReply = ref<boolean>(false);
|
||||||
|
|
||||||
|
function fileOpen(url: string) {
|
||||||
|
window.open(url, "_blank");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<q-dialog v-model="modal">
|
||||||
|
<q-card class="my-card" style="width: 700px; max-width: 80vw">
|
||||||
|
<!-- title -->
|
||||||
|
<q-item>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-avatar>
|
||||||
|
<q-icon name="mail_outline" color="teal" size="1.4em" />
|
||||||
|
</q-avatar>
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ detail.subject }}</q-item-label>
|
||||||
|
|
||||||
|
<q-item-label caption>
|
||||||
|
วันที่ได้รับ {{ detail.receiveDate }}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section side top>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
icon="mdi-reply"
|
||||||
|
color="grey-7"
|
||||||
|
@click="(modalReply = true), (modal = false)"
|
||||||
|
>
|
||||||
|
<q-tooltip>ตอบกลับข้อความ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<!-- body -->
|
||||||
|
<q-card-section style="padding: 2px">
|
||||||
|
<q-card-section class="col-12">
|
||||||
|
{{ detail.body }}
|
||||||
|
</q-card-section>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<!-- file -->
|
||||||
|
<q-card-actions v-if="detail.payload">
|
||||||
|
<q-btn flat color="grey-5" icon="mdi-paperclip"
|
||||||
|
>ดาวน์โหลดเอกสารแนบ
|
||||||
|
<q-menu max-width="480px">
|
||||||
|
<q-list
|
||||||
|
v-for="(item, index) in detail.payload.attachments"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<q-item clickable v-close-popup @click.stop="fileOpen(item.url)">
|
||||||
|
<q-item-section>{{ item.name }}</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-separator />
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
<q-tooltip>ดาวน์โหลดเอกสารแนบ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
|
||||||
|
<PopupReplyInbox
|
||||||
|
:modal="modalReply"
|
||||||
|
:idInbox="detail.no"
|
||||||
|
:click-close="() => (modalReply = false)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -7,6 +7,7 @@ import http from "@/plugins/http";
|
||||||
import config from "@/app.config";
|
import config from "@/app.config";
|
||||||
import { useCounterMixin } from "@/stores/mixin";
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
import PopupReplyInbox from "@/components/PopupReplyInbox.vue";
|
import PopupReplyInbox from "@/components/PopupReplyInbox.vue";
|
||||||
|
import PopupDetailInbox from "@/components/PopupDetailInbox.vue";
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const mixin = useCounterMixin();
|
const mixin = useCounterMixin();
|
||||||
|
|
@ -82,14 +83,15 @@ const items = ref<any>([
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchlistInbox();
|
await fetchlistInbox(1);
|
||||||
});
|
});
|
||||||
const fetchlistInbox = async () => {
|
const fetchlistInbox = async (index: number) => {
|
||||||
showLoader();
|
index === 1 && showLoader();
|
||||||
await http
|
await http
|
||||||
.get(config.API.msgInbox)
|
.get(config.API.msgInbox + `?page=${index}&pageSize=${10}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
let data = res.data.result;
|
let data = res.data.result.data;
|
||||||
|
totalInbox.value = res.data.result.total;
|
||||||
let listItem: any = [];
|
let listItem: any = [];
|
||||||
data.map((e: any) => {
|
data.map((e: any) => {
|
||||||
listItem.push({
|
listItem.push({
|
||||||
|
|
@ -100,11 +102,13 @@ const fetchlistInbox = async () => {
|
||||||
: e.createdFullName,
|
: e.createdFullName,
|
||||||
subject: e.subject ?? "",
|
subject: e.subject ?? "",
|
||||||
timereceive: date2Thai(e.createdAt),
|
timereceive: date2Thai(e.createdAt),
|
||||||
body: e.body ?? "",
|
body: e.body ?? "-",
|
||||||
ratingModel: 0,
|
ratingModel: 0,
|
||||||
|
receiveDate: date2Thai(e.receiveDate),
|
||||||
|
payload: e.payload,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
inboxList.value = listItem;
|
inboxList.value.push(...listItem);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|
@ -130,6 +134,38 @@ function modalReplyClose() {
|
||||||
contactNo.value = "";
|
contactNo.value = "";
|
||||||
modalReply.value = false;
|
modalReply.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataInbox = ref<any>();
|
||||||
|
const modalDetial = ref<boolean>(false);
|
||||||
|
function onClickOpenPopupDetail(data: any) {
|
||||||
|
dataInbox.value = data;
|
||||||
|
link.value = data.no;
|
||||||
|
modalDetial.value = !modalDetial.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModalDetail(val: boolean) {
|
||||||
|
modalDetial.value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollTargetRef = ref<any>(null);
|
||||||
|
const totalInbox = ref<number>(0);
|
||||||
|
function onLoad(index: number, done: any) {
|
||||||
|
if (inboxList.value.length < totalInbox.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
fetchlistInbox(index + 1);
|
||||||
|
done();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function onLoadRef(index: number, done: any) {
|
||||||
|
// if (inboxList.value.length < totalInbox.value) {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// fetchlistInbox(index + 1);
|
||||||
|
// done();
|
||||||
|
// }, 2000);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -184,7 +220,7 @@ function modalReplyClose() {
|
||||||
<q-card
|
<q-card
|
||||||
flat
|
flat
|
||||||
bordered
|
bordered
|
||||||
:style="$q.screen.gt.xs ? 'max-height: 74vh' : 'height: auto;'"
|
:style="$q.screen.gt.xs ? 'max-height: 74vh' : 'height: 100px;'"
|
||||||
class="q-pb-md col-12"
|
class="q-pb-md col-12"
|
||||||
>
|
>
|
||||||
<div class="col-12 row q-pa-md">
|
<div class="col-12 row q-pa-md">
|
||||||
|
|
@ -200,8 +236,73 @@ function modalReplyClose() {
|
||||||
flat
|
flat
|
||||||
/> -->
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="totalInbox != 0"
|
||||||
|
ref="scrollTargetRef"
|
||||||
|
class="q-pa-md"
|
||||||
|
style="max-height: 90%; overflow: auto"
|
||||||
|
>
|
||||||
|
<q-infinite-scroll
|
||||||
|
@load="onLoad"
|
||||||
|
:offset="250"
|
||||||
|
class="q-pa-md"
|
||||||
|
:scroll-target="scrollTargetRef"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in inboxList"
|
||||||
|
:key="index"
|
||||||
|
class="caption"
|
||||||
|
>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
v-ripple
|
||||||
|
class="q-py-md q-mb-sm my-menu"
|
||||||
|
:active="link === item.no"
|
||||||
|
active-class="my-menu-link"
|
||||||
|
@click="onClickOpenPopupDetail(item)"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>
|
||||||
|
{{ item.sender }}
|
||||||
|
<q-icon
|
||||||
|
v-if="item.payload"
|
||||||
|
name="mdi-paperclip"
|
||||||
|
color="grey-6"
|
||||||
|
size="18px"
|
||||||
|
/></q-item-label>
|
||||||
|
<q-item-label caption class="text-grey-6" lines="2">{{
|
||||||
|
item.subject
|
||||||
|
}}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
<q-scroll-area style="height: 64vh" v-if="inboxList.length > 0">
|
<q-item-section side top>
|
||||||
|
<q-item-label caption>{{ item.timereceive }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section side top>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
icon="mdi-reply"
|
||||||
|
size="10px"
|
||||||
|
color="grey-7"
|
||||||
|
@click="dialogRepleOpen(item.no)"
|
||||||
|
>
|
||||||
|
<q-tooltip>ตอบกลับข้อความ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
<template v-slot:loading v-if="inboxList.length < totalInbox">
|
||||||
|
<div class="row justify-center q-my-md">
|
||||||
|
<q-spinner-dots color="primary" size="40px" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</q-infinite-scroll>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <q-scroll-area style="height: 64vh" v-if="inboxList.length > 0">
|
||||||
<q-list
|
<q-list
|
||||||
v-for="(contact, index) in inboxList"
|
v-for="(contact, index) in inboxList"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
@ -212,11 +313,18 @@ function modalReplyClose() {
|
||||||
v-ripple
|
v-ripple
|
||||||
class="q-py-md q-mb-sm my-menu"
|
class="q-py-md q-mb-sm my-menu"
|
||||||
:active="link === contact.no"
|
:active="link === contact.no"
|
||||||
@click="link = contact.no"
|
|
||||||
active-class="my-menu-link"
|
active-class="my-menu-link"
|
||||||
|
@click="onClickOpenPopupDetail(contact)"
|
||||||
>
|
>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>{{ contact.sender }}</q-item-label>
|
<q-item-label>
|
||||||
|
{{ contact.sender }}
|
||||||
|
<q-icon
|
||||||
|
v-if="contact.payload"
|
||||||
|
name="mdi-paperclip"
|
||||||
|
color="grey-6"
|
||||||
|
size="18px"
|
||||||
|
/></q-item-label>
|
||||||
<q-item-label caption class="text-grey-6" lines="2">{{
|
<q-item-label caption class="text-grey-6" lines="2">{{
|
||||||
contact.subject
|
contact.subject
|
||||||
}}</q-item-label>
|
}}</q-item-label>
|
||||||
|
|
@ -241,7 +349,7 @@ function modalReplyClose() {
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
</q-scroll-area>
|
</q-scroll-area> -->
|
||||||
<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>
|
||||||
<div class="text-yellow-10">
|
<div class="text-yellow-10">
|
||||||
<q-icon
|
<q-icon
|
||||||
|
|
@ -261,6 +369,12 @@ function modalReplyClose() {
|
||||||
:idInbox="contactNo"
|
:idInbox="contactNo"
|
||||||
:click-close="modalReplyClose"
|
:click-close="modalReplyClose"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<PopupDetailInbox
|
||||||
|
:modal="modalDetial"
|
||||||
|
:data="dataInbox"
|
||||||
|
@update:modal="updateModalDetail"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style>
|
||||||
.my-menu-link {
|
.my-menu-link {
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,6 @@ async function fetcheSigner(id: string) {
|
||||||
formCommand.commanderAbovePosition = data.commanderAbovePosition;
|
formCommand.commanderAbovePosition = data.commanderAbovePosition;
|
||||||
formCommand.author = data.author;
|
formCommand.author = data.author;
|
||||||
formCommand.subject = data.subject;
|
formCommand.subject = data.subject;
|
||||||
|
|
||||||
store.statusUpload = true;
|
store.statusUpload = true;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
@ -452,9 +451,11 @@ watch(
|
||||||
<template>
|
<template>
|
||||||
<div class="col-12 q-pa-md">
|
<div class="col-12 q-pa-md">
|
||||||
<!-- ผลงาน -->
|
<!-- ผลงาน -->
|
||||||
<div class="col-12 ">
|
<div class="col-12">
|
||||||
<q-card bordered class="cardSp1 col-12">
|
<q-card bordered class="cardSp1 col-12">
|
||||||
<div class="text-weight-medium bg-grey-1 col-12 q-py-sm q-px-md">ผลงาน</div>
|
<div class="text-weight-medium bg-grey-1 col-12 q-py-sm q-px-md">
|
||||||
|
ผลงาน
|
||||||
|
</div>
|
||||||
<div class="col-12"><q-separator /></div>
|
<div class="col-12"><q-separator /></div>
|
||||||
<div class="col-12 q-pa-sm">
|
<div class="col-12 q-pa-sm">
|
||||||
<div class="row q-col-gutter-sm">
|
<div class="row q-col-gutter-sm">
|
||||||
|
|
@ -462,39 +463,39 @@ watch(
|
||||||
ผู้บังคับบัญชาชั้นต้น
|
ผู้บังคับบัญชาชั้นต้น
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
:readonly="store.currentStep != 2 || store.statusUpload"
|
:readonly="store.currentStep != 2 || store.statusUpload"
|
||||||
ref="performanceRef"
|
ref="performanceRef"
|
||||||
dense
|
dense
|
||||||
class="col-xs-12 col-sm-6"
|
class="col-xs-12 col-sm-6"
|
||||||
outlined
|
outlined
|
||||||
label="ชื่อผลงาน"
|
label="ชื่อผลงาน"
|
||||||
v-model="formCommand.subject"
|
v-model="formCommand.subject"
|
||||||
@update:model-value="updateInput(formCommand)"
|
@update:model-value="updateInput(formCommand)"
|
||||||
:rules="[(val) => !!val || `${'กรุณากรอกชื่อผลงาน'}`]"
|
:rules="[(val) => !!val || `${'กรุณากรอกชื่อผลงาน'}`]"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
/>
|
/>
|
||||||
<q-input
|
<q-input
|
||||||
:readonly="store.currentStep != 2 || store.statusUpload"
|
:readonly="store.currentStep != 2 || store.statusUpload"
|
||||||
ref="performanceOwnerRef"
|
ref="performanceOwnerRef"
|
||||||
class="col-xs-12 col-sm-6"
|
class="col-xs-12 col-sm-6"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
v-model="formCommand.author"
|
v-model="formCommand.author"
|
||||||
@update:model-value="updateInput(formCommand)"
|
@update:model-value="updateInput(formCommand)"
|
||||||
label="เจ้าของผลงาน"
|
label="เจ้าของผลงาน"
|
||||||
:rules="[(val) => !!val || `${'กรุณากรอกเจ้าของผลงาน'}`]"
|
:rules="[(val) => !!val || `${'กรุณากรอกเจ้าของผลงาน'}`]"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- เลือกผู้เซ็นเอกสาร -->
|
<!-- เลือกผู้เซ็นเอกสาร -->
|
||||||
<div class="col-12 ">
|
<div class="col-12">
|
||||||
<q-card bordered class="cardSp1 col-12">
|
<q-card bordered class="cardSp1 col-12">
|
||||||
<div class="text-weight-medium bg-grey-1 q-py-sm q-px-md">
|
<div class="text-weight-medium bg-grey-1 q-py-sm q-px-md">
|
||||||
เลือกผู้เซ็นเอกสาร
|
เลือกผู้เซ็นเอกสาร
|
||||||
|
|
@ -576,11 +577,13 @@ watch(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- v-if="store.statusUpload -->
|
<!-- v-if="store.statusUpload -->
|
||||||
<div class="row q-col-gutter-sm" >
|
<div class="row q-col-gutter-sm">
|
||||||
<!-- แบบพิจารณาคุณสมบัติบุคคล -->
|
<!-- แบบพิจารณาคุณสมบัติบุคคล -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<q-card bordered class="cardSp1">
|
||||||
<div class="col-12 row items-center text-weight-medium bg-grey-1 q-pl-md q-pr-sm">
|
<div
|
||||||
|
class="col-12 row items-center text-weight-medium bg-grey-1 q-pl-md q-pr-sm"
|
||||||
|
>
|
||||||
<div>แบบพิจารณาคุณสมบัติบุคคล</div>
|
<div>แบบพิจารณาคุณสมบัติบุคคล</div>
|
||||||
<q-space />
|
<q-space />
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -667,11 +670,13 @@ watch(
|
||||||
<!-- แบบแสดงรายละเอียดการเสนอผลงาน -->
|
<!-- แบบแสดงรายละเอียดการเสนอผลงาน -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<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
|
||||||
|
class="text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm col-12 row items-center"
|
||||||
|
>
|
||||||
<div>แบบแสดงรายละเอียดการเสนอผลงาน</div>
|
<div>แบบแสดงรายละเอียดการเสนอผลงาน</div>
|
||||||
<q-space />
|
<q-space />
|
||||||
<div>
|
<div>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
dense
|
dense
|
||||||
icon="download"
|
icon="download"
|
||||||
|
|
@ -686,9 +691,9 @@ watch(
|
||||||
>
|
>
|
||||||
<q-tooltip> ดาวน์โหลดต้นแบบ </q-tooltip></q-btn
|
<q-tooltip> ดาวน์โหลดต้นแบบ </q-tooltip></q-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="downloadFile2 != ''"
|
v-if="downloadFile2 != ''"
|
||||||
:href="downloadFile2"
|
:href="downloadFile2"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
@ -706,45 +711,45 @@ watch(
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 q-pa-sm">
|
<div class="col-12 q-pa-sm">
|
||||||
<div class="row q-col-gutter-md col-12">
|
<div class="row q-col-gutter-md col-12">
|
||||||
<q-file
|
<q-file
|
||||||
ref="fileEvaluation2Ref"
|
ref="fileEvaluation2Ref"
|
||||||
v-model="fileEvaluation2"
|
v-model="fileEvaluation2"
|
||||||
:disable="!store.statusUpload"
|
:disable="!store.statusUpload"
|
||||||
class="col-12"
|
class="col-12"
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
accept=".pdf"
|
accept=".pdf"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
:rules="
|
:rules="
|
||||||
downloadFile2 === ''
|
downloadFile2 === ''
|
||||||
? [(val) => !!val || 'กรุณาเลือกไฟล์']
|
? [(val) => !!val || 'กรุณาเลือกไฟล์']
|
||||||
: []
|
: []
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<q-icon name="attach_file" />
|
<q-icon name="attach_file" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<q-btn
|
<q-btn
|
||||||
:disable="!store.statusUpload"
|
:disable="!store.statusUpload"
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
dense
|
dense
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="mdi-upload"
|
icon="mdi-upload"
|
||||||
@click="
|
@click="
|
||||||
fetchPathUpload(
|
fetchPathUpload(
|
||||||
'เล่ม 1',
|
'เล่ม 1',
|
||||||
evaluateId,
|
evaluateId,
|
||||||
'2-แบบแสดงรายละเอียดการเสนอผลงาน',
|
'2-แบบแสดงรายละเอียดการเสนอผลงาน',
|
||||||
fileEvaluation2
|
fileEvaluation2
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</q-file>
|
</q-file>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -754,93 +759,101 @@ watch(
|
||||||
<!-- แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก) -->
|
<!-- แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก) -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<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>แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล
|
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm no-wrap"
|
||||||
(เอกสารแบบ ก.)
|
>
|
||||||
|
<div>
|
||||||
|
แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล
|
||||||
|
(เอกสารแบบ ก.)
|
||||||
</div>
|
</div>
|
||||||
<q-space />
|
<q-space />
|
||||||
<div >
|
<div>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
dense
|
dense
|
||||||
icon="download"
|
icon="download"
|
||||||
color="indigo"
|
color="indigo"
|
||||||
@click="
|
@click="
|
||||||
onClickDowloadFile(
|
onClickDowloadFile(
|
||||||
'EV1_007',
|
'EV1_007',
|
||||||
'template-3',
|
'template-3',
|
||||||
'แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)'
|
'แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)'
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<q-tooltip> ดาวน์โหลดต้นแบบ </q-tooltip></q-btn
|
<q-tooltip> ดาวน์โหลดต้นแบบ </q-tooltip></q-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="downloadFile3 != ''">
|
<div v-if="downloadFile3 != ''">
|
||||||
<q-btn
|
<q-btn
|
||||||
:href="downloadFile3"
|
:href="downloadFile3"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
flat
|
flat
|
||||||
dense
|
dense
|
||||||
icon="visibility"
|
icon="visibility"
|
||||||
class="q-ml-sm"
|
class="q-ml-sm"
|
||||||
color="blue"
|
color="blue"
|
||||||
>
|
>
|
||||||
<q-tooltip> ดูไฟล์เอกสาร </q-tooltip></q-btn
|
<q-tooltip> ดูไฟล์เอกสาร </q-tooltip></q-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12"><q-separator /></div>
|
<div class="col-12"><q-separator /></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 q-pa-sm">
|
<div class="col-12 q-pa-sm">
|
||||||
<q-file
|
<q-file
|
||||||
ref="fileEvaluation3Ref"
|
ref="fileEvaluation3Ref"
|
||||||
v-model="fileEvaluation3"
|
v-model="fileEvaluation3"
|
||||||
:disable="!store.statusUpload"
|
:disable="!store.statusUpload"
|
||||||
class="col-12"
|
class="col-12"
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
accept=".pdf"
|
accept=".pdf"
|
||||||
:rules="
|
:rules="
|
||||||
downloadFile3 === ''
|
downloadFile3 === ''
|
||||||
? [(val) => !!val || 'กรุณาเลือกไฟล์']
|
? [(val) => !!val || 'กรุณาเลือกไฟล์']
|
||||||
: []
|
: []
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<q-icon name="attach_file" />
|
<q-icon name="attach_file" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<q-btn
|
<q-btn
|
||||||
:disable="!store.statusUpload"
|
:disable="!store.statusUpload"
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
dense
|
dense
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="mdi-upload"
|
icon="mdi-upload"
|
||||||
@click="
|
@click="
|
||||||
fetchPathUpload(
|
fetchPathUpload(
|
||||||
'เล่ม 1',
|
'เล่ม 1',
|
||||||
evaluateId,
|
evaluateId,
|
||||||
'3-แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)',
|
'3-แบบตรวจสอบความถูกต้องครบถ้วนของข้อมูลเพื่อประกอบการคัดเลือกบุคคล (เอกสารแบบ ก)',
|
||||||
fileEvaluation3
|
fileEvaluation3
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn>
|
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</q-file>
|
</q-file>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- แบบสรุปข้อมูลของผู้ขอรับการคัดเลือก (เอกสารหมายเลข 9) -->
|
<!-- แบบสรุปข้อมูลของผู้ขอรับการคัดเลือก (เอกสารหมายเลข 9) -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<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 class="col-7">แบบสรุปข้อมูลของผู้ขอรับการคัดเลือก (เอกสารหมายเลข 9)</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 />
|
<q-space />
|
||||||
<div>
|
<div>
|
||||||
<q-btn
|
<q-btn
|
||||||
|
|
@ -920,11 +933,12 @@ watch(
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- แบบประเมินคุณลักษณะบุคคล -->
|
<!-- แบบประเมินคุณลักษณะบุคคล -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<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
|
||||||
|
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm items-center"
|
||||||
|
>
|
||||||
<div>แบบประเมินคุณลักษณะบุคคล</div>
|
<div>แบบประเมินคุณลักษณะบุคคล</div>
|
||||||
<q-space />
|
<q-space />
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -983,21 +997,22 @@ watch(
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
dense
|
dense
|
||||||
:disable="!store.statusUpload"
|
:disable="!store.statusUpload"
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="mdi-upload"
|
icon="mdi-upload"
|
||||||
@click="
|
@click="
|
||||||
fetchPathUpload(
|
fetchPathUpload(
|
||||||
'เล่ม 1',
|
'เล่ม 1',
|
||||||
evaluateId,
|
evaluateId,
|
||||||
'4-แบบประเมินคุณลักษณะบุคคล',
|
'4-แบบประเมินคุณลักษณะบุคคล',
|
||||||
fileEvaluation4
|
fileEvaluation4
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn>
|
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</q-file>
|
</q-file>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1005,11 +1020,12 @@ watch(
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!--ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11) -->
|
<!--ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11) -->
|
||||||
<div class="col-6" v-if="store.currentStep === 2">
|
<div class="col-6" v-if="store.currentStep === 2">
|
||||||
<q-card bordered class="cardSp1">
|
<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
|
||||||
|
class="col-12 row text-weight-medium bg-grey-1 q-py-sm q-pl-md q-pr-sm items-center"
|
||||||
|
>
|
||||||
<div>ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11)</div>
|
<div>ผลงานที่จะส่งประเมิน (เอกสารหมายเลข 11)</div>
|
||||||
<q-space />
|
<q-space />
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -1082,7 +1098,8 @@ watch(
|
||||||
fileEvaluation6
|
fileEvaluation6
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn>
|
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</q-file>
|
</q-file>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ function checkDoc() {
|
||||||
.get(
|
.get(
|
||||||
config.API.loadFileDocument(
|
config.API.loadFileDocument(
|
||||||
"เล่ม 2",
|
"เล่ม 2",
|
||||||
store.evaluateId,
|
evaluateId.value,
|
||||||
"2-เอกสารเล่ม 2 (ฉบับแก้ไข)"
|
"2-เอกสารเล่ม 2 (ฉบับแก้ไข)"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -157,7 +157,7 @@ async function fetcheSigner(id: string) {
|
||||||
|
|
||||||
/** lifecycleHook*/
|
/** lifecycleHook*/
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await checkDoc();
|
await checkDoc();
|
||||||
await fetcheSigner(evaluateId.value);
|
await fetcheSigner(evaluateId.value);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -207,25 +207,25 @@ onMounted(async () => {
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<q-card class=" shadow-0" bordered style="border: 1px solid #d6dee1">
|
<q-card class="shadow-0" bordered style="border: 1px solid #d6dee1">
|
||||||
<div class="row col-12 bg-grey-1">
|
<div class="row col-12 bg-grey-1">
|
||||||
<div class="text-weight-medium q-py-sm q-px-md">
|
<div class="text-weight-medium q-py-sm q-px-md">
|
||||||
เอกสารเล่ม 2 (ฉบับแก้ไข)
|
เอกสารเล่ม 2 (ฉบับแก้ไข)
|
||||||
</div>
|
</div>
|
||||||
<q-space/>
|
<q-space />
|
||||||
<div v-if="downloadUrl != ''">
|
|
||||||
<q-btn
|
<q-btn
|
||||||
:href="downloadUrl"
|
v-if="downloadUrl != ''"
|
||||||
target="_blank"
|
:href="downloadUrl"
|
||||||
class="col-12"
|
target="_blank"
|
||||||
outline
|
class="q-ml-sm"
|
||||||
icon="visibility"
|
color="blue"
|
||||||
label="ดูไฟล์เอกสาร"
|
flat
|
||||||
color="primary"
|
dense
|
||||||
>
|
icon="visibility"
|
||||||
<q-tooltip> ดูไฟล์เอกสาร </q-tooltip></q-btn
|
>
|
||||||
>
|
<q-tooltip> ดูไฟล์เอกสาร </q-tooltip></q-btn
|
||||||
</div>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12"><q-separator /></div>
|
<div class="col-12"><q-separator /></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,18 @@ const link = ref<string>("");
|
||||||
* เรียกฟังก์ชันทั้งหมดตอนเรียกใช้ไฟล์นี้
|
* เรียกฟังก์ชันทั้งหมดตอนเรียกใช้ไฟล์นี้
|
||||||
*/
|
*/
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchlistNotification();
|
await fetchlistNotification(1);
|
||||||
if (keycloak.tokenParsed != null) {
|
if (keycloak.tokenParsed != null) {
|
||||||
fullname.value = keycloak.tokenParsed.name;
|
fullname.value = keycloak.tokenParsed.name;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchlistNotification = async () => {
|
const fetchlistNotification = async (index: number) => {
|
||||||
await http
|
await http
|
||||||
.get(config.API.msgNotificate)
|
.get(config.API.msgNotificate + `?page=${index}&pageSize=${20}`)
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
const data = res.data.result;
|
const data = res.data.result.data;
|
||||||
|
totalInbox.value = res.data.result.total;
|
||||||
let list: any[] = [];
|
let list: any[] = [];
|
||||||
data.map((e: any) => {
|
data.map((e: any) => {
|
||||||
list.push({
|
list.push({
|
||||||
|
|
@ -49,7 +50,7 @@ const fetchlistNotification = async () => {
|
||||||
timereceive: date2Thai(e.createdAt),
|
timereceive: date2Thai(e.createdAt),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
notiList.value = list;
|
notiList.value.push(...list);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|
@ -71,6 +72,16 @@ const doLogout = () => {
|
||||||
keycloak.logout();
|
keycloak.logout();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const totalInbox = ref<number>(0);
|
||||||
|
function onLoad(index: any, done: any) {
|
||||||
|
if (notiList.value.length < totalInbox.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
fetchlistNotification(index + 1);
|
||||||
|
done();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<!-- โครงเว็บ -->
|
<!-- โครงเว็บ -->
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -125,7 +136,6 @@ const doLogout = () => {
|
||||||
label="การลา"
|
label="การลา"
|
||||||
icon="mdi-calendar-blank-outline"
|
icon="mdi-calendar-blank-outline"
|
||||||
@click="router.push(`/leave`)"
|
@click="router.push(`/leave`)"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -147,7 +157,7 @@ const doLogout = () => {
|
||||||
color="negative"
|
color="negative"
|
||||||
text-color="white"
|
text-color="white"
|
||||||
floating
|
floating
|
||||||
>{{ notiList.length }}</q-badge
|
>{{ totalInbox }}</q-badge
|
||||||
>
|
>
|
||||||
<q-menu v-model="notiTrigger" max-width="480px" :offset="[0, 10]">
|
<q-menu v-model="notiTrigger" max-width="480px" :offset="[0, 10]">
|
||||||
<div class="q-px-md q-py-sm row col-12 items-center">
|
<div class="q-px-md q-py-sm row col-12 items-center">
|
||||||
|
|
@ -162,7 +172,61 @@ const doLogout = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-list
|
<q-infinite-scroll
|
||||||
|
@load="onLoad"
|
||||||
|
:offset="250"
|
||||||
|
style="min-width: 300px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in notiList"
|
||||||
|
:key="index"
|
||||||
|
class="caption"
|
||||||
|
>
|
||||||
|
<q-item v-ripple class="mytry q-py-sm" dense>
|
||||||
|
<q-item-section avatar top style="min-width: 10px">
|
||||||
|
<q-avatar
|
||||||
|
rounded
|
||||||
|
color="primary"
|
||||||
|
size="25px"
|
||||||
|
text-color="white"
|
||||||
|
>
|
||||||
|
<span class="text-weight-medium text-uppercase">{{
|
||||||
|
item.sender[0]
|
||||||
|
}}</span>
|
||||||
|
</q-avatar>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption class="text-black">{{
|
||||||
|
item.body
|
||||||
|
}}</q-item-label>
|
||||||
|
<q-item-label
|
||||||
|
caption
|
||||||
|
class="row items-center text-grey-7"
|
||||||
|
style="font-size: 12px"
|
||||||
|
>{{ item.timereceive }}</q-item-label
|
||||||
|
>
|
||||||
|
</q-item-section>
|
||||||
|
<div>
|
||||||
|
<q-btn
|
||||||
|
size="sm"
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
icon="mdi-close"
|
||||||
|
class="mybtn q-mx-xs"
|
||||||
|
v-close-popup
|
||||||
|
></q-btn>
|
||||||
|
</div>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-slot:loading v-if="notiList.length < totalInbox">
|
||||||
|
<div class="row justify-center q-my-md">
|
||||||
|
<q-spinner-dots color="primary" size="40px" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</q-infinite-scroll>
|
||||||
|
|
||||||
|
<!-- <q-list
|
||||||
style="min-width: 300px"
|
style="min-width: 300px"
|
||||||
v-for="(n, index) in notiList"
|
v-for="(n, index) in notiList"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
@ -208,7 +272,7 @@ const doLogout = () => {
|
||||||
v-if="index + 1 < notiList.length"
|
v-if="index + 1 < notiList.length"
|
||||||
:key="index"
|
:key="index"
|
||||||
/>
|
/>
|
||||||
</q-list>
|
</q-list> -->
|
||||||
</q-menu>
|
</q-menu>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue