ทะเบียนประวัติ: ปรับแท็บข้อมูลส่วนตัว

This commit is contained in:
oat_dev 2024-04-02 10:00:41 +07:00
parent 0e63cefa5d
commit 11abca5e07
5 changed files with 1730 additions and 1538 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, useAttrs, reactive } from "vue"; import { onMounted, ref, useAttrs, reactive, watch } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import axios from "axios"; import axios from "axios";
@ -27,7 +27,7 @@ const {
hideLoader, hideLoader,
dialogRemove, dialogRemove,
} = mixin; } = mixin;
const submitDisable = ref<boolean>(true);
const { fetchPerson } = store; const { fetchPerson } = store;
const profileId = ref<string>(route.params.id.toString()); const profileId = ref<string>(route.params.id.toString());
const editId = ref<string>(""); const editId = ref<string>("");
@ -47,6 +47,9 @@ const changeNameData = reactive<any>({
status: "", status: "",
documentId: "", documentId: "",
}); });
const prefixChange = ref<string>("");
const firstNameChange = ref<string>("");
const lastNameChange = ref<string>("");
const profileInfo = ref<any>([]); const profileInfo = ref<any>([]);
@ -81,8 +84,8 @@ const historyVisibleColumns = ref<String[]>([
"firstName", "firstName",
"lastName", "lastName",
"status", "status",
"createdFullName", "lastUpdateFullName",
"createdAt", "lastUpdatedAt",
]); ]);
const rows = ref<ResponseObject[]>([]); const rows = ref<ResponseObject[]>([]);
const historyRows = ref<ResponseObject[]>([]); const historyRows = ref<ResponseObject[]>([]);
@ -179,22 +182,22 @@ const historyColumns = ref<QTableProps["columns"]>([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
{ {
name: "createdFullName", name: "lastUpdateFullName",
align: "left", align: "left",
label: "ผู้ดำเนินการ", label: "ผู้ดำเนินการ",
sortable: true, sortable: true,
field: "createdFullName", field: "lastUpdateFullName",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) => sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
{ {
name: "createdAt", name: "lastUpdatedAt",
align: "left", align: "left",
label: "วันที่แก้ไข", label: "วันที่แก้ไข",
sortable: true, sortable: true,
field: "createdAt", field: "lastUpdatedAt",
format: (v) => date2Thai(v), format: (v) => date2Thai(v),
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
@ -213,13 +216,23 @@ const pagination = ref({
rowsPerPage: 10, rowsPerPage: 10,
}); });
const historyPagination = ref({
page: 1,
rowsPerPage: 10,
});
function editForm(row: any) { function editForm(row: any) {
submitDisable.value = true;
dialogStatus.value = "edit"; dialogStatus.value = "edit";
editId.value = row.id; editId.value = row.id;
subId.value = row.id;
changeNameData.prefix = row.prefix; changeNameData.prefix = row.prefix;
changeNameData.firstName = row.firstName; changeNameData.firstName = row.firstName;
changeNameData.lastName = row.lastName; changeNameData.lastName = row.lastName;
changeNameData.status = row.status; changeNameData.status = row.status;
prefixChange.value = changeNameData.prefix;
firstNameChange.value = changeNameData.firstName;
lastNameChange.value = changeNameData.lastName;
dialog.value = true; dialog.value = true;
} }
@ -229,7 +242,7 @@ function closeDialog() {
} }
async function onSubmit() { async function onSubmit() {
if (!!fileUpload.value) { if (!!fileUpload.value || dialogStatus.value === "edit") {
await dialogConfirm( await dialogConfirm(
$q, $q,
async () => { async () => {
@ -238,7 +251,9 @@ async function onSubmit() {
? await addData() ? await addData()
: await editData(editId.value); : await editData(editId.value);
closeDialog(); closeDialog();
await uploadProfile(fileUpload.value); if (!!fileUpload.value) {
await uploadProfile(fileUpload.value);
}
}, },
"ยืนยันการบันทึกข้อมูล", "ยืนยันการบันทึกข้อมูล",
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?" "ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
@ -287,6 +302,7 @@ async function uploadFileURL(uploadUrl: string, file: any) {
.then(() => { .then(() => {
// fetchProfile(profileId.value); // fetchProfile(profileId.value);
// success($q, ""); // success($q, "");
fileUpload.value = undefined;
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
@ -486,6 +502,39 @@ function filterSelector(val: string, update: Function, refData: string) {
break; break;
} }
} }
watch(
() => changeNameData.prefix,
() => {
if (changeNameData.prefix !== prefixChange.value) {
submitDisable.value = false;
} else {
submitDisable.value = true;
}
}
);
watch(
() => changeNameData.firstName,
() => {
if (changeNameData.firstName !== firstNameChange.value) {
submitDisable.value = false;
} else {
submitDisable.value = true;
}
}
);
watch(
() => changeNameData.lastName,
() => {
if (changeNameData.lastName !== lastNameChange.value) {
submitDisable.value = false;
} else {
submitDisable.value = true;
}
}
);
</script> </script>
<template> <template>
@ -500,8 +549,12 @@ function filterSelector(val: string, update: Function, refData: string) {
changeNameData.prefix = profileInfo.prefix; changeNameData.prefix = profileInfo.prefix;
changeNameData.firstName = profileInfo.firstName; changeNameData.firstName = profileInfo.firstName;
changeNameData.lastName = profileInfo.lastName; changeNameData.lastName = profileInfo.lastName;
prefixChange = changeNameData.prefix;
firstNameChange = changeNameData.firstName;
lastNameChange = changeNameData.lastName;
changeNameData.status = ''; changeNameData.status = '';
dialogStatus = 'create'; dialogStatus = 'create';
submitDisable = true;
dialog = true; dialog = true;
} }
" "
@ -545,13 +598,12 @@ function filterSelector(val: string, update: Function, refData: string) {
virtual-scroll virtual-scroll
ref="table" ref="table"
v-bind="attrs" v-bind="attrs"
v-model:pagination="pagination"
:rows="rows" :rows="rows"
:columns="columns" :columns="columns"
:filter="filterSearch" :filter="filterSearch"
:rows-per-page-options="[0]" :rows-per-page-options="[0]"
:pagination="initialPagination"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:pagination-label="paginationLabel"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
> >
<template v-slot:header="props"> <template v-slot:header="props">
@ -630,325 +682,351 @@ function filterSelector(val: string, update: Function, refData: string) {
</template> </template>
</d-table> </d-table>
<q-dialog v-model="dialog" class="dialog" persistent> <q-dialog v-model="dialog" persistent>
<q-card style="min-width: 50%" class="bg-white"> <q-layout
view="lHh lpr lFf"
container
style="height: 80vh"
class="bg-white"
>
<q-form @submit.prevent greedy @validation-success="onSubmit()"> <q-form @submit.prevent greedy @validation-success="onSubmit()">
<q-card-section class="flex justify-between" style="padding: 0"> <q-header>
<dialog-header <q-toolbar>
:tittle="dialogStatus === 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'" <dialog-header
:close="closeDialog" :tittle="dialogStatus === 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'"
/> :close="closeDialog"
</q-card-section> />
<q-separator color="grey-4" /> </q-toolbar>
<div class="q-pa-md"> <q-separator color="grey-4" />
<div class="row q-mb-md"> </q-header>
<div class="col-5">
<q-select <q-page-container>
outlined <q-page class="q-pa-md">
v-model="changeNameData.status" <div class="row q-mb-sm">
:options="statusOption" <div class="col-5">
label="สถานะการเปลี่ยนชื่อ" <q-select
use-input outlined
input-debounce="0" v-model="changeNameData.status"
:rules="[ :options="statusOption"
(val) => !!val || `${'กรุณาเลือกสถานะการเปลี่ยนชื่อ'}`, label="สถานะการเปลี่ยนชื่อ"
]" use-input
@filter="(inputValue:string, hide-bottom-space
input-debounce="0"
:rules="[
(val) => !!val || `${'กรุณาเลือกสถานะการเปลี่ยนชื่อ'}`,
]"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'statusOptions' doneFn:Function) => filterSelector(inputValue, doneFn,'statusOptions'
) " ) "
dense dense
/> />
</div>
</div> </div>
</div> <div class="row q-gutter-sm q-mb-md">
<div class="row q-gutter-md q-mb-md"> <div class="col">
<div class="col"> <q-select
<q-select :readonly="
:readonly=" !changeNameData.status ||
!changeNameData.status || (changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ' &&
(changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ' && changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' &&
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' && changeNameData.status !==
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' &&
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' && changeNameData.status !==
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล') "
" v-model="changeNameData.prefix"
v-model="changeNameData.prefix" :options="store.Ops.prefixOps"
:options="store.Ops.prefixOps" label="คำนำหน้าชื่อ"
label="คำนำหน้าชื่อ" dense
dense :class="
:class=" !changeNameData.status ||
!changeNameData.status || (changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ' &&
(changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ' && changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' &&
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' && changeNameData.status !==
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' &&
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' && changeNameData.status !==
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล') ? ''
? '' : 'inputgreen'
: 'inputgreen' "
" outlined
outlined use-input
use-input lazy-rules
lazy-rules emit-value
emit-value map-options
map-options :rules="[(val) => !!val || `${'กรุณาเลือกคำนำหน้าชื่อ'}`]"
:rules="[(val) => !!val || `${'กรุณาเลือกคำนำหน้าชื่อ'}`]" hide-bottom-space
hide-bottom-space input-debounce="0"
input-debounce="0" option-label="name"
option-label="name" option-value="name"
option-value="name" @filter="(inputValue:string,
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'prefixOps' doneFn:Function) => filterSelector(inputValue, doneFn,'prefixOps'
) " ) "
/> />
</div>
<div class="col">
<q-input
:readonly="
!changeNameData.status ||
(changeNameData.status !== 'เปลี่ยนชื่อ' &&
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' &&
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
"
outlined
v-model="changeNameData.firstName"
label="ชื่อ"
bg-color="white"
dense
:class="
!changeNameData.status ||
(changeNameData.status !== 'เปลี่ยนชื่อ' &&
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' &&
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
? ''
: 'inputgreen'
"
:rules="[(val) => !!val || `${'กรุณากรอกชื่อ'}`]"
hide-bottom-space
/>
</div>
<div class="col">
<q-input
:readonly="
!changeNameData.status ||
(changeNameData.status !== 'เปลี่ยนนามสกุล' &&
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
"
outlined
v-model="changeNameData.lastName"
label="นามสกุล"
bg-color="white"
dense
:class="
!changeNameData.status ||
(changeNameData.status !== 'เปลี่ยนนามสกุล' &&
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
? ''
: 'inputgreen'
"
:rules="[(val) => !!val || `${'กรุณากรอกนามสกุล'}`]"
hide-bottom-space
/>
</div>
</div> </div>
<div class="col"> <div class="row">
<q-input <q-uploader
:readonly=" color="gray"
!changeNameData.status || type="file"
(changeNameData.status !== 'เปลี่ยนชื่อ' && flat
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' && ref="uploader"
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' && class="full-width"
changeNameData.status !== text-color="white"
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล') :max-size="10000000"
" accept=".jpg,.png,.pdf,.csv,.doc,.docx"
outlined bordered
v-model="changeNameData.firstName" label="[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
label="ชื่อ" @added="(v) => (fileUpload = v[0])"
bg-color="white" >
dense <template v-slot:header="scope">
:class=" <div class="row no-wrap items-center q-pa-sm q-gutter-xs">
!changeNameData.status || <q-btn
(changeNameData.status !== 'เปลี่ยนชื่อ' && v-if="scope.queuedFiles.length > 0"
changeNameData.status !== 'เปลี่ยนคำนำหน้าชื่อ และชื่อ' && icon="clear_all"
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' && @click="scope.removeQueuedFiles"
changeNameData.status !== round
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล') dense
? '' flat
: 'inputgreen' >
" <q-tooltip>ลบทงหมด</q-tooltip>
:rules="[(val) => !!val || `${'กรุณากรอกชื่อ'}`]" </q-btn>
hide-bottom-space <q-btn
/> v-if="scope.uploadedFiles.length > 0"
</div> icon="done_all"
<div class="col"> @click="scope.removeUploadedFiles"
<q-input round
:readonly=" dense
!changeNameData.status || flat
(changeNameData.status !== 'เปลี่ยนนามสกุล' && >
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' && <q-tooltip>ลบไฟลปโหลด</q-tooltip>
changeNameData.status !== </q-btn>
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' && <q-spinner
changeNameData.status !== v-if="scope.isUploading"
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล') class="q-uploader__spinner"
" />
outlined <div class="col">
v-model="changeNameData.lastName" <div class="q-uploader__title">
label="นามสกุล" {{ "[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]" }}
bg-color="white" </div>
dense <div class="q-uploader__subtitle">
:class=" {{ scope.uploadSizeLabel }} /
!changeNameData.status || {{ scope.uploadProgressLabel }}
(changeNameData.status !== 'เปลี่ยนนามสกุล' && </div>
changeNameData.status !== 'เปลี่ยนชื่อ-นามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และนามสกุล' &&
changeNameData.status !==
'เปลี่ยนคำนำหน้าชื่อ และชื่อ-นามสกุล')
? ''
: 'inputgreen'
"
:rules="[(val) => !!val || `${'กรุณากรอกนามสกุล'}`]"
hide-bottom-space
/>
</div>
</div>
<div class="row">
<q-uploader
color="gray"
type="file"
flat
ref="uploader"
class="full-width"
text-color="white"
:max-size="10000000"
accept=".jpg,.png,.pdf,.csv,.doc,.docx"
bordered
label="[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
@added="(v) => (fileUpload = v[0])"
>
<template v-slot:header="scope">
<div class="row no-wrap items-center q-pa-sm q-gutter-xs">
<q-btn
v-if="scope.queuedFiles.length > 0"
icon="clear_all"
@click="scope.removeQueuedFiles"
round
dense
flat
>
<q-tooltip>ลบทงหมด</q-tooltip>
</q-btn>
<q-btn
v-if="scope.uploadedFiles.length > 0"
icon="done_all"
@click="scope.removeUploadedFiles"
round
dense
flat
>
<q-tooltip>ลบไฟลปโหลด</q-tooltip>
</q-btn>
<q-spinner
v-if="scope.isUploading"
class="q-uploader__spinner"
/>
<div class="col">
<div class="q-uploader__title">
{{ "[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]" }}
</div>
<div class="q-uploader__subtitle">
{{ scope.uploadSizeLabel }} /
{{ scope.uploadProgressLabel }}
</div> </div>
<q-btn
v-if="scope.canAddFiles"
type="a"
icon="add_box"
@click="scope.pickFiles"
round
dense
flat
>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
v-if="scope.isUploading"
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div> </div>
<q-btn </template>
v-if="scope.canAddFiles" </q-uploader>
type="a" <div
icon="add_box" v-if="alertUpload && dialogStatus === 'create'"
@click="scope.pickFiles" class="row text-negative items-center q-mt-sm"
round >
dense กรณาอพโหลดเอกสาร
flat <q-icon name="mdi-alert-circle q-ml-sm" size="24px" />
> </div>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
v-if="scope.isUploading"
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div>
</template>
</q-uploader>
<div
v-if="alertUpload"
class="row text-negative items-center q-mt-sm"
>
กรณาอพโหลดเอกสาร
<q-icon name="mdi-alert-circle q-ml-sm" size="24px" />
</div> </div>
</div> </q-page>
</div> </q-page-container>
<q-card-actions align="right">
<q-btn <q-footer>
id="onSubmit" <q-separator color="grey-4" />
type="submit" <q-toolbar class="fit row wrap justify-end items-start content-start">
dense <q-btn
unelevated id="onSubmit"
label="บันทึก" type="submit"
color="public" dense
class="q-px-md" :disable="submitDisable"
@click=" unelevated
() => { label="บันทึก"
if (!!fileUpload) { color="public"
alertUpload = false; class="q-px-md"
} else { @click="
alertUpload = true; () => {
if (!!fileUpload && dialogStatus === 'create') {
alertUpload = false;
} else {
alertUpload = true;
}
} }
} "
" >
> <q-tooltip>นทกขอม</q-tooltip>
<q-tooltip>นทกขอม</q-tooltip> </q-btn>
</q-btn> </q-toolbar>
</q-card-actions> </q-footer>
</q-form> </q-form>
</q-card> </q-layout>
</q-dialog> </q-dialog>
<q-dialog v-model="historyDialog" class="dialog" persistent> <q-dialog v-model="historyDialog" class="dialog" persistent>
<q-card style="min-width: 70%" class="bg-white"> <q-layout
<q-card-section class="flex justify-between" style="padding: 0"> view="lHh lpr lFf"
<dialog-header container
tittle="ประวัติแก้ไขการเปลี่ยนชื่อ-นามสกุล" style="height: 80vh; min-width: 80%"
:close="closeHistoryDialog" class="bg-white"
/> >
</q-card-section> <q-header>
<q-separator color="grey-4" /> <q-toolbar>
<q-card-section> <dialog-header
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm"> tittle="ประวัติแก้ไขการเปลี่ยนชื่อ-นามสกุล"
<q-space /> :close="closeHistoryDialog"
<q-input
dense
outlined
bg-color="white"
v-model="historyKeyword"
label="ค้นหา"
class="q-mr-sm"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<q-select
v-model="historyVisibleColumns"
multiple
outlined
dense
bg-color="white"
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="historyColumns"
option-value="name"
options-cover
style="min-width: 150px"
/> />
</q-toolbar> </q-toolbar>
<d-table <q-separator color="grey-4" />
ref="table" </q-header>
:columns="historyColumns"
:rows="historyRows" <q-page-container>
row-key="name" <q-page class="q-pa-md">
flat <q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
bordered <q-space />
:paging="true" <q-input
dense dense
:filter="historyKeyword" outlined
v-model:pagination="pagination" bg-color="white"
:rows-per-page-options="[20, 50, 100]" v-model="historyKeyword"
class="custom-header-table" label="ค้นหา"
:visible-columns="historyVisibleColumns" class="q-mr-sm"
> >
<template v-slot:header="props"> <template v-slot:append>
<q-tr :props="props"> <q-icon name="search" />
<q-th v-for="col in props.cols" :key="col.name" :props="props"> </template>
<span class="text-weight-medium">{{ col.label }}</span> </q-input>
</q-th>
<q-th auto-width /> <q-select
</q-tr> v-model="historyVisibleColumns"
</template> multiple
<template v-slot:body="props"> outlined
<q-tr :props="props" class="cursor-pointer"> dense
<q-td v-for="col in props.cols" :key="col.id"> bg-color="white"
<div> options-dense
{{ col.value === "" ? "-" : col.value }} :display-value="$q.lang.table.columns"
</div> emit-value
</q-td> map-options
<q-td auto-width> </q-td> :options="historyColumns"
</q-tr> option-value="name"
</template> options-cover
</d-table> style="min-width: 150px"
</q-card-section> />
</q-card> </q-toolbar>
<d-table
ref="table"
:columns="historyColumns"
:rows="historyRows"
row-key="name"
flat
bordered
:paging="true"
dense
:filter="historyKeyword"
v-model:pagination="historyPagination"
:rows-per-page-options="[20, 50, 100]"
class="custom-header-table"
:visible-columns="historyVisibleColumns"
>
<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-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value === "" ? "-" : col.value }}
</div>
</q-td>
<q-td auto-width> </q-td>
</q-tr>
</template>
</d-table>
</q-page>
</q-page-container>
</q-layout>
</q-dialog> </q-dialog>
</template> </template>

View file

@ -566,133 +566,22 @@ onMounted(async () => {
<!-- Edit Dialog --> <!-- Edit Dialog -->
<q-dialog v-model="modal" persistent> <q-dialog v-model="modal" persistent>
<q-card style="width: 600px"> <q-layout
view="lHh lpr lFf"
container
style="height: 80vh"
class="bg-white"
>
<q-form greedy @submit.prevent @validation-success="onSubmit"> <q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader tittle="แก้ไขข้อมูลที่อยู่" :close="clickClose" /> <q-header>
<q-separator /> <q-toolbar>
<!-- regis address --> <DialogHeader tittle="แก้ไขข้อมูลที่อยู่" :close="clickClose" />
<q-card-section class="q-p-sm"> </q-toolbar>
<div class="col-12 q-pb-xs"> <q-separator color="grey-4" />
<q-input </q-header>
dense
outlined <q-page-container>
lazy-rules <q-page class="q-pa-md">
hide-bottom-space
type="textarea"
class="inputgreen"
v-model="formData.registrationAddress"
:label="dataLabel.registrationAddress"
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ตามทะเบียนบ้าน'}`]"
/>
</div>
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.registrationProvinceId"
:options="store.Ops.provinceOps"
:label="dataLabel.registrationProvince"
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
@update:model-value="(value:string) => selectProvince(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.registrationDistrictId"
:options="store.Ops.districtOps"
:label="dataLabel.registrationDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
@update:model-value="(value:string) => selectDistrict(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.registrationSubDistrictId"
:options="store.Ops.subdistrictOps"
:label="dataLabel.registrationSubDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
@update:model-value="(value:string) => selectSubDistrict(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-input
dense
readonly
outlined
lazy-rules
hide-bottom-space
v-model="formData.registrationZipCode"
:label="dataLabel.registrationZipCode"
/>
</div>
</div>
<!-- same address ? -->
<div class="col-xs-12 q-gutter-sm items-center flex q-my-sm">
<label class="text-medium"
>อยจจนตรงกบทอยตามทะเบยนบาน</label
>
<q-radio
dense
val="1"
label="ใช่"
checked-icon="task_alt"
class="inputgreen"
v-model="sameAddress"
unchecked-icon="panorama_fish_eye"
/>
<q-radio
dense
val="0"
label="ไม่"
checked-icon="task_alt"
class="inputgreen"
v-model="sameAddress"
unchecked-icon="panorama_fish_eye"
/>
</div>
<!-- current address -->
<div v-if="sameAddress === '0'">
<div class="col-12 q-pb-xs"> <div class="col-12 q-pb-xs">
<q-input <q-input
dense dense
@ -701,9 +590,9 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
type="textarea" type="textarea"
class="inputgreen" class="inputgreen"
v-model="formData.currentAddress" v-model="formData.registrationAddress"
:label="dataLabel.currentAddress" :label="dataLabel.registrationAddress"
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ปัจจุบัน'}`]" :rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ตามทะเบียนบ้าน'}`]"
/> />
</div> </div>
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs"> <div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
@ -720,11 +609,11 @@ onMounted(async () => {
option-label="name" option-label="name"
input-debounce="0" input-debounce="0"
class="inputgreen" class="inputgreen"
v-model="formData.currentProvinceId" v-model="formData.registrationProvinceId"
:options="store.Ops.provinceOps" :options="store.Ops.provinceOps"
:label="dataLabel.currentProvince" :label="dataLabel.registrationProvince"
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]" :rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
@update:model-value="(value:string) => selectProvince(value, '2')" @update:model-value="(value:string) => selectProvince(value, '1')"
@filter="(inputValue:string, @filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps' doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
) " ) "
@ -743,11 +632,11 @@ onMounted(async () => {
option-label="name" option-label="name"
input-debounce="0" input-debounce="0"
class="inputgreen" class="inputgreen"
v-model="formData.currentDistrictId" v-model="formData.registrationDistrictId"
:options="store.Ops.districtCOps" :options="store.Ops.districtOps"
:label="dataLabel.currentDistrict" :label="dataLabel.registrationDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]" :rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
@update:model-value="(value:string) => selectDistrict(value, '2')" @update:model-value="(value:string) => selectDistrict(value, '1')"
@filter="(inputValue:string, @filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps' doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps'
) " ) "
@ -766,11 +655,11 @@ onMounted(async () => {
option-label="name" option-label="name"
input-debounce="0" input-debounce="0"
class="inputgreen" class="inputgreen"
v-model="formData.currentSubDistrictId" v-model="formData.registrationSubDistrictId"
:options="store.Ops.subdistrictCOps" :options="store.Ops.subdistrictOps"
:label="dataLabel.currentSubDistrict" :label="dataLabel.registrationSubDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]" :rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
@update:model-value="(value:string) => selectSubDistrict(value, '2')" @update:model-value="(value:string) => selectSubDistrict(value, '1')"
@filter="(inputValue:string, @filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps' doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps'
) " ) "
@ -783,127 +672,249 @@ onMounted(async () => {
outlined outlined
lazy-rules lazy-rules
hide-bottom-space hide-bottom-space
v-model="formData.currentZipCode" v-model="formData.registrationZipCode"
:label="dataLabel.registrationZipCode" :label="dataLabel.registrationZipCode"
/> />
</div> </div>
</div> </div>
</div> <!-- same address ? -->
</q-card-section> <div class="col-xs-12 q-gutter-sm items-center flex q-my-sm">
<label class="text-medium"
>อยจจนตรงกบทอยตามทะเบยนบาน</label
>
<q-radio
dense
val="1"
label="ใช่"
checked-icon="task_alt"
class="inputgreen"
v-model="sameAddress"
unchecked-icon="panorama_fish_eye"
/>
<q-radio
dense
val="0"
label="ไม่"
checked-icon="task_alt"
class="inputgreen"
v-model="sameAddress"
unchecked-icon="panorama_fish_eye"
/>
</div>
<!-- current address -->
<div v-if="sameAddress === '0'">
<div class="col-12 q-pb-xs">
<q-input
dense
outlined
lazy-rules
hide-bottom-space
type="textarea"
class="inputgreen"
v-model="formData.currentAddress"
:label="dataLabel.currentAddress"
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ปัจจุบัน'}`]"
/>
</div>
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentProvinceId"
:options="store.Ops.provinceOps"
:label="dataLabel.currentProvince"
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
@update:model-value="(value:string) => selectProvince(value, '2')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentDistrictId"
:options="store.Ops.districtCOps"
:label="dataLabel.currentDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
@update:model-value="(value:string) => selectDistrict(value, '2')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-select
dense
outlined
use-input
lazy-rules
emit-value
map-options
hide-bottom-space
option-value="id"
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentSubDistrictId"
:options="store.Ops.subdistrictCOps"
:label="dataLabel.currentSubDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
@update:model-value="(value:string) => selectSubDistrict(value, '2')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-input
dense
readonly
outlined
lazy-rules
hide-bottom-space
v-model="formData.currentZipCode"
:label="dataLabel.registrationZipCode"
/>
</div>
</div>
</div>
</q-page>
</q-page-container>
<q-separator /> <q-separator />
<div class="text-right q-pa-sm"> <q-footer>
<q-btn <q-separator color="grey-4" />
dense <q-toolbar class="fit row wrap justify-end items-start content-start">
unelevated <q-btn
id="onSubmit" dense
type="submit" unelevated
label="บันทึก" label="บันทึก"
color="public" id="onSubmit"
class="q-px-md" type="submit"
> color="public"
<q-tooltip>นท</q-tooltip> class="q-px-md"
</q-btn> >
</div> <q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-toolbar>
</q-footer>
</q-form> </q-form>
</q-card> </q-layout>
</q-dialog> </q-dialog>
<q-dialog v-model="modalHistory" persistent> <q-dialog v-model="modalHistory" persistent>
<q-card style="min-width: 80%"> <q-layout
<q-card-section class="flex justify-between" style="padding: 0"> view="lHh lpr lFf"
<DialogHeader container
tittle="ประวัติแก้ไขข้อมูลที่อยู่" style="height: 80vh; min-width: 80%"
:close="() => (modalHistory = false)" class="bg-white"
/> >
</q-card-section> <q-header>
<q-toolbar>
<q-separator /> <DialogHeader
<q-card-section class="q-p-sm"> tittle="ประวัติแก้ไขข้อมูลที่อยู่"
<div class="row q-gutter-sm q-mb-sm"> :close="() => (modalHistory = false)"
<q-space />
<q-input
standout
dense
v-model="filterHistory"
ref="filterRef"
outlined
placeholder="ค้นหา"
debounce="300"
>
<template v-slot:append>
<q-icon
v-if="filterHistory == ''"
name="search"
@click.stop.prevent="filterHistory = ''"
class="cursor-pointer"
/>
<q-icon
v-if="filterHistory"
name="cancel"
@click.stop.prevent="filterHistory = ''"
class="cursor-pointer"
/>
</template>
</q-input>
<q-select
v-model="visibleColumnsHistory"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columnsHistory"
option-value="name"
options-cover
style="min-width: 150px"
/> />
</div> </q-toolbar>
<d-table <q-separator color="grey-4" />
ref="table" </q-header>
flat
bordered
dense
:columns="columnsHistory"
:rows="rowsHistory"
:paging="true"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumnsHistory"
:filter="filterHistory"
>
>
<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 in props.cols" :key="col.id">
<div>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope"> <q-page-container>
<q-pagination <q-page class="q-pa-md">
v-model="currentPage" <div class="row q-gutter-sm q-mb-sm">
active-color="primary" <q-space />
color="dark" <q-input
:max="Number(maxPage)" standout
size="sm" dense
boundary-links v-model="filterHistory"
direction-links ref="filterRef"
></q-pagination> outlined
</template> placeholder="ค้นหา"
</d-table> debounce="300"
</q-card-section> >
</q-card> <template v-slot:append>
<q-icon
v-if="filterHistory == ''"
name="search"
@click.stop.prevent="filterHistory = ''"
class="cursor-pointer"
/>
<q-icon
v-if="filterHistory"
name="cancel"
@click.stop.prevent="filterHistory = ''"
class="cursor-pointer"
/>
</template>
</q-input>
<q-select
v-model="visibleColumnsHistory"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columnsHistory"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
<d-table
ref="table"
flat
bordered
dense
:columns="columnsHistory"
:rows="rowsHistory"
:paging="true"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumnsHistory"
:filter="filterHistory"
>
>
<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 in props.cols" :key="col.id">
<div>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
</q-page>
</q-page-container>
</q-layout>
</q-dialog> </q-dialog>
</template> </template>

View file

@ -448,6 +448,11 @@ const pagination = ref({
rowsPerPage: 10, rowsPerPage: 10,
}); });
const historyPagination = ref({
page: 1,
rowsPerPage: 10,
});
const visibleColumns = ref<string[]>([ const visibleColumns = ref<string[]>([
"educationLevel", "educationLevel",
"institute", "institute",
@ -628,6 +633,7 @@ async function addData() {
...educationData, ...educationData,
startYear: undefined, startYear: undefined,
endYear: undefined, endYear: undefined,
isDate: isDate.value === "false" ? false : true,
}) })
.then(() => { .then(() => {
fetchData(id.value); fetchData(id.value);
@ -648,6 +654,7 @@ function editData(idData: string) {
profileId: undefined, profileId: undefined,
startYear: undefined, startYear: undefined,
endYear: undefined, endYear: undefined,
isDate: isDate.value === "false" ? false : true,
}) })
.then(() => { .then(() => {
fetchData(id.value); fetchData(id.value);
@ -958,7 +965,11 @@ onMounted(async () => {
<q-header> <q-header>
<q-toolbar> <q-toolbar>
<dialog-header <dialog-header
:tittle="dialogStatus == 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'" :tittle="
dialogStatus == 'edit'
? 'แก้ไขข้อมูลประวัติการศึกษา'
: 'เพิ่มข้อมูลประวัติการศึกษา'
"
:close="closeDialog" :close="closeDialog"
/> />
</q-toolbar> </q-toolbar>
@ -1410,82 +1421,92 @@ onMounted(async () => {
</q-dialog> </q-dialog>
<q-dialog v-model="historyDialog" class="dialog" persistent> <q-dialog v-model="historyDialog" class="dialog" persistent>
<q-card style="min-width: 70%" class="bg-white"> <q-layout
<q-card-section class="flex justify-between" style="padding: 0"> view="lHh lpr lFf"
<dialog-header container
tittle="ประวัติแก้ไขประวัติการศึกษา" style="height: 80vh; min-width: 80%"
:close="closeHistoryDialog" class="bg-white"
/> >
</q-card-section> <q-header>
<q-separator color="grey-4" /> <q-toolbar>
<q-card-section> <dialog-header
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm"> tittle="ประวัติแก้ไขประวัติการศึกษา"
<q-space /> :close="closeHistoryDialog"
<q-input
dense
outlined
bg-color="white"
v-model="historyKeyword"
label="ค้นหา"
class="q-mr-sm"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<q-select
v-model="historyVisibleColumns"
multiple
outlined
dense
bg-color="white"
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="historyColumns"
option-value="name"
options-cover
style="min-width: 150px"
/> />
</q-toolbar> </q-toolbar>
<d-table <q-separator color="grey-4" />
ref="table" </q-header>
:columns="historyColumns"
:rows="historyRows" <q-page-container>
row-key="name" <q-page class="q-pa-md">
flat <q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
bordered <q-space />
:paging="true" <q-input
dense dense
:filter="historyKeyword" outlined
v-model:pagination="pagination" bg-color="white"
:rows-per-page-options="[20, 50, 100]" v-model="historyKeyword"
class="custom-header-table" label="ค้นหา"
:visible-columns="historyVisibleColumns" class="q-mr-sm"
> >
<template v-slot:header="props"> <template v-slot:append>
<q-tr :props="props"> <q-icon name="search" />
<q-th v-for="col in props.cols" :key="col.name" :props="props"> </template>
<span class="text-weight-medium">{{ col.label }}</span> </q-input>
</q-th>
<q-th auto-width /> <q-select
</q-tr> v-model="historyVisibleColumns"
</template> multiple
<template v-slot:body="props"> outlined
<q-tr :props="props" class="cursor-pointer"> dense
<q-td v-for="col in props.cols" :key="col.id"> bg-color="white"
<div> options-dense
{{ col.value === "" ? "-" : col.value }} :display-value="$q.lang.table.columns"
</div> emit-value
</q-td> map-options
<q-td auto-width> </q-td> :options="historyColumns"
</q-tr> option-value="name"
</template> options-cover
</d-table> style="min-width: 150px"
</q-card-section> />
</q-card> </q-toolbar>
<d-table
ref="table"
:columns="historyColumns"
:rows="historyRows"
row-key="name"
flat
bordered
:paging="true"
dense
:filter="historyKeyword"
v-model:pagination="historyPagination"
:rows-per-page-options="[20, 50, 100]"
class="custom-header-table"
:visible-columns="historyVisibleColumns"
>
<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-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value === "" ? "-" : col.value }}
</div>
</q-td>
<q-td auto-width> </q-td>
</q-tr>
</template>
</d-table>
</q-page>
</q-page-container>
</q-layout>
</q-dialog> </q-dialog>
</template> </template>

View file

@ -165,6 +165,11 @@ const pagination = ref({
rowsPerPage: 10, rowsPerPage: 10,
}); });
const historyPagination = ref({
page: 1,
rowsPerPage: 10,
});
const visibleColumns = ref<string[]>([ const visibleColumns = ref<string[]>([
"field", "field",
"detail", "detail",
@ -238,7 +243,6 @@ async function fetchHistoryData(id: string) {
.get(config.API.profileNewAbilityHisByAbilityId(id)) .get(config.API.profileNewAbilityHisByAbilityId(id))
.then(async (res) => { .then(async (res) => {
historyRows.value = res.data.result; historyRows.value = res.data.result;
console.log(res.data.result);
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
@ -434,19 +438,6 @@ onMounted(async () => {
> >
<q-tooltip>ประวแกไขความสามารถพเศษ</q-tooltip> <q-tooltip>ประวแกไขความสามารถพเศษ</q-tooltip>
</q-btn> </q-btn>
<q-btn
color="red"
flat
dense
round
size="14px"
icon="mdi-delete"
clickable
@click.stop="deleteData(props.row.id)"
v-close-popup
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
@ -504,151 +495,185 @@ onMounted(async () => {
</d-table> </d-table>
<q-dialog v-model="dialog" class="dialog" persistent> <q-dialog v-model="dialog" class="dialog" persistent>
<q-card style="min-width: 40%" class="bg-white"> <q-layout
view="lHh lpr lFf"
container
style="height: 80vh"
class="bg-white"
>
<q-form @submit.prevent greedy @validation-success="onSubmit()"> <q-form @submit.prevent greedy @validation-success="onSubmit()">
<q-card-section class="flex justify-between" style="padding: 0"> <q-header>
<dialog-header <q-toolbar>
:tittle="dialogStatus == 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'" <dialog-header
:close="closeDialog" :tittle="
/> dialogStatus == 'edit'
</q-card-section> ? 'แก้ไขข้อมูลความสามารถพิเศษ'
<q-separator color="grey-4" /> : 'เพิ่มข้อมูลความสามารถพิเศษ'
<q-card-section class="col q-gutter-sm q-pr-md"> "
<div class="row q-gutter-sm q-ml-none"> :close="closeDialog"
<div class="col"> />
<q-input </q-toolbar>
outlined <q-separator color="grey-4" />
class="inputgreen" </q-header>
dense
bg-color="white" <q-page-container>
v-model="specialSkill.field" <q-page class="q-pa-md">
label="ด้าน" <div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
hide-bottom-space <div class="col-xs-6 col-sm-6 col-md-6">
:rules="[(val) => !!val || `${'กรุณากรอกด้านความสามารถพิเศษ'}`]" <q-input
/> outlined
class="inputgreen"
dense
bg-color="white"
v-model="specialSkill.field"
label="ด้าน"
hide-bottom-space
:rules="[
(val) => !!val || `${'กรุณากรอกด้านความสามารถพิเศษ'}`,
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<q-input
outlined
dense
class="inputgreen"
bg-color="white"
v-model="specialSkill.detail"
label="รายละเอียด"
hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
/>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<q-input
class="inputgreen"
outlined
dense
bg-color="white"
v-model="specialSkill.remark"
label="หมายเหตุ"
/>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<q-input
class="inputgreen"
outlined
dense
bg-color="white"
v-model="specialSkill.reference"
label="เอกสารอ้างอิง"
/>
</div>
</div> </div>
<div class="col"> </q-page>
<q-input </q-page-container>
outlined
dense <q-footer>
class="inputgreen" <q-separator color="grey-4" />
bg-color="white" <q-toolbar class="fit row wrap justify-end items-start content-start">
v-model="specialSkill.detail" <q-btn
label="รายละเอียด" dense
hide-bottom-space unelevated
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]" label="บันทึก"
/> id="onSubmit"
</div> type="submit"
</div> color="public"
<q-input class="q-px-md"
class="col-12 inputgreen" >
outlined <q-tooltip>นทกขอม</q-tooltip>
dense </q-btn>
bg-color="white" </q-toolbar>
v-model="specialSkill.remark" </q-footer>
label="หมายเหตุ"
/>
<q-input
class="col-12 inputgreen"
outlined
dense
bg-color="white"
v-model="specialSkill.reference"
label="เอกสารอ้างอิง"
/>
</q-card-section>
<q-card-actions align="right">
<q-btn
id="onSubmit"
type="submit"
dense
unelevated
label="บันทึก"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-card-actions>
</q-form> </q-form>
</q-card> </q-layout>
</q-dialog> </q-dialog>
<q-dialog v-model="historyDialog" class="dialog" persistent> <q-dialog v-model="historyDialog" class="dialog" persistent>
<q-card style="min-width: 70%" class="bg-white"> <q-layout
<q-card-section class="flex justify-between" style="padding: 0"> view="lHh lpr lFf"
<dialog-header container
tittle="ประวัติแก้ไขความสามารถพิเศษ" style="height: 80vh; min-width: 80%"
:close="closeHistoryDialog" class="bg-white"
/> >
</q-card-section> <q-header>
<q-separator color="grey-4" /> <q-toolbar>
<q-card-section> <dialog-header
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm"> tittle="ประวัติแก้ไขความสามารถพิเศษ"
<q-space /> :close="closeHistoryDialog"
<q-input
dense
outlined
bg-color="white"
v-model="historyKeyword"
label="ค้นหา"
class="q-mr-sm"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<q-select
v-model="historyVisibleColumns"
multiple
outlined
dense
bg-color="white"
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="historyColumns"
option-value="name"
options-cover
style="min-width: 150px"
/> />
</q-toolbar> </q-toolbar>
<d-table <q-separator color="grey-4" />
ref="table" </q-header>
:columns="historyColumns"
:rows="historyRows" <q-page-container>
row-key="name" <q-page class="q-pa-md">
flat <q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
bordered <q-space />
:paging="true" <q-input
dense dense
:filter="historyKeyword" outlined
v-model:pagination="pagination" bg-color="white"
:rows-per-page-options="[20, 50, 100]" v-model="historyKeyword"
class="custom-header-table" label="ค้นหา"
:visible-columns="historyVisibleColumns" class="q-mr-sm"
> >
<template v-slot:header="props"> <template v-slot:append>
<q-tr :props="props"> <q-icon name="search" />
<q-th v-for="col in props.cols" :key="col.name" :props="props"> </template>
<span class="text-weight-medium">{{ col.label }}</span> </q-input>
</q-th>
<q-th auto-width /> <q-select
</q-tr> v-model="historyVisibleColumns"
</template> multiple
<template v-slot:body="props" v-if="mode === 'table'"> outlined
<q-tr :props="props" class="cursor-pointer"> dense
<q-td v-for="col in props.cols" :key="col.id"> bg-color="white"
<div>{{ col.value ? col.value : "-" }}</div> options-dense
</q-td> :display-value="$q.lang.table.columns"
<q-td auto-width> </q-td> emit-value
</q-tr> map-options
</template> :options="historyColumns"
</d-table> option-value="name"
</q-card-section> options-cover
</q-card> style="min-width: 150px"
/>
</q-toolbar>
<d-table
ref="table"
:columns="historyColumns"
:rows="historyRows"
row-key="name"
flat
bordered
:paging="true"
dense
:filter="historyKeyword"
v-model:pagination="historyPagination"
:rows-per-page-options="[20, 50, 100]"
class="custom-header-table"
:visible-columns="historyVisibleColumns"
>
<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-slot:body="props" v-if="mode === 'table'">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.id">
<div>{{ col.value ? col.value : "-" }}</div>
</q-td>
<q-td auto-width> </q-td>
</q-tr>
</template>
</d-table>
</q-page>
</q-page-container>
</q-layout>
</q-dialog> </q-dialog>
</template> </template>