Merge branch 'develop' into devTee

This commit is contained in:
STW_TTTY\stwtt 2024-04-02 10:25:59 +07:00
commit db27f7d3f5
9 changed files with 1851 additions and 1588 deletions

View file

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

View file

@ -566,133 +566,22 @@ onMounted(async () => {
<!-- Edit Dialog -->
<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">
<DialogHeader tittle="แก้ไขข้อมูลที่อยู่" :close="clickClose" />
<q-separator />
<!-- regis address -->
<q-card-section class="q-p-sm">
<div class="col-12 q-pb-xs">
<q-input
dense
outlined
lazy-rules
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'">
<q-header>
<q-toolbar>
<DialogHeader tittle="แก้ไขข้อมูลที่อยู่" :close="clickClose" />
</q-toolbar>
<q-separator color="grey-4" />
</q-header>
<q-page-container>
<q-page class="q-pa-md">
<div class="col-12 q-pb-xs">
<q-input
dense
@ -701,9 +590,9 @@ onMounted(async () => {
hide-bottom-space
type="textarea"
class="inputgreen"
v-model="formData.currentAddress"
:label="dataLabel.currentAddress"
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ปัจจุบัน'}`]"
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">
@ -720,11 +609,11 @@ onMounted(async () => {
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentProvinceId"
v-model="formData.registrationProvinceId"
:options="store.Ops.provinceOps"
:label="dataLabel.currentProvince"
:label="dataLabel.registrationProvince"
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
@update:model-value="(value:string) => selectProvince(value, '2')"
@update:model-value="(value:string) => selectProvince(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
) "
@ -743,11 +632,11 @@ onMounted(async () => {
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentDistrictId"
:options="store.Ops.districtCOps"
:label="dataLabel.currentDistrict"
v-model="formData.registrationDistrictId"
:options="store.Ops.districtOps"
:label="dataLabel.registrationDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
@update:model-value="(value:string) => selectDistrict(value, '2')"
@update:model-value="(value:string) => selectDistrict(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps'
) "
@ -766,11 +655,11 @@ onMounted(async () => {
option-label="name"
input-debounce="0"
class="inputgreen"
v-model="formData.currentSubDistrictId"
:options="store.Ops.subdistrictCOps"
:label="dataLabel.currentSubDistrict"
v-model="formData.registrationSubDistrictId"
:options="store.Ops.subdistrictOps"
:label="dataLabel.registrationSubDistrict"
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
@update:model-value="(value:string) => selectSubDistrict(value, '2')"
@update:model-value="(value:string) => selectSubDistrict(value, '1')"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps'
) "
@ -783,127 +672,249 @@ onMounted(async () => {
outlined
lazy-rules
hide-bottom-space
v-model="formData.currentZipCode"
v-model="formData.registrationZipCode"
:label="dataLabel.registrationZipCode"
/>
</div>
</div>
</div>
</q-card-section>
<!-- 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">
<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 />
<div class="text-right q-pa-sm">
<q-btn
dense
unelevated
id="onSubmit"
type="submit"
label="บันทึก"
color="public"
class="q-px-md"
>
<q-tooltip>นท</q-tooltip>
</q-btn>
</div>
<q-footer>
<q-separator color="grey-4" />
<q-toolbar class="fit row wrap justify-end items-start content-start">
<q-btn
dense
unelevated
label="บันทึก"
id="onSubmit"
type="submit"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-toolbar>
</q-footer>
</q-form>
</q-card>
</q-layout>
</q-dialog>
<q-dialog v-model="modalHistory" persistent>
<q-card style="min-width: 80%">
<q-card-section class="flex justify-between" style="padding: 0">
<DialogHeader
tittle="ประวัติแก้ไขข้อมูลที่อยู่"
:close="() => (modalHistory = false)"
/>
</q-card-section>
<q-separator />
<q-card-section class="q-p-sm">
<div class="row q-gutter-sm q-mb-sm">
<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"
<q-layout
view="lHh lpr lFf"
container
style="height: 80vh; min-width: 80%"
class="bg-white"
>
<q-header>
<q-toolbar>
<DialogHeader
tittle="ประวัติแก้ไขข้อมูลที่อยู่"
:close="() => (modalHistory = false)"
/>
</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>
</q-toolbar>
<q-separator color="grey-4" />
</q-header>
<template v-slot:pagination="scope">
<q-pagination
v-model="currentPage"
active-color="primary"
color="dark"
:max="Number(maxPage)"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</d-table>
</q-card-section>
</q-card>
<q-page-container>
<q-page class="q-pa-md">
<div class="row q-gutter-sm q-mb-sm">
<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>
<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>
</template>

View file

@ -448,6 +448,11 @@ const pagination = ref({
rowsPerPage: 10,
});
const historyPagination = ref({
page: 1,
rowsPerPage: 10,
});
const visibleColumns = ref<string[]>([
"educationLevel",
"institute",
@ -628,6 +633,7 @@ async function addData() {
...educationData,
startYear: undefined,
endYear: undefined,
isDate: isDate.value === "false" ? false : true,
})
.then(() => {
fetchData(id.value);
@ -648,6 +654,7 @@ function editData(idData: string) {
profileId: undefined,
startYear: undefined,
endYear: undefined,
isDate: isDate.value === "false" ? false : true,
})
.then(() => {
fetchData(id.value);
@ -958,7 +965,11 @@ onMounted(async () => {
<q-header>
<q-toolbar>
<dialog-header
:tittle="dialogStatus == 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'"
:tittle="
dialogStatus == 'edit'
? 'แก้ไขข้อมูลประวัติการศึกษา'
: 'เพิ่มข้อมูลประวัติการศึกษา'
"
:close="closeDialog"
/>
</q-toolbar>
@ -1410,82 +1421,92 @@ onMounted(async () => {
</q-dialog>
<q-dialog v-model="historyDialog" class="dialog" persistent>
<q-card style="min-width: 70%" class="bg-white">
<q-card-section class="flex justify-between" style="padding: 0">
<dialog-header
tittle="ประวัติแก้ไขประวัติการศึกษา"
:close="closeHistoryDialog"
/>
</q-card-section>
<q-separator color="grey-4" />
<q-card-section>
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
<q-space />
<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-layout
view="lHh lpr lFf"
container
style="height: 80vh; min-width: 80%"
class="bg-white"
>
<q-header>
<q-toolbar>
<dialog-header
tittle="ประวัติแก้ไขประวัติการศึกษา"
:close="closeHistoryDialog"
/>
</q-toolbar>
<d-table
ref="table"
:columns="historyColumns"
:rows="historyRows"
row-key="name"
flat
bordered
:paging="true"
dense
:filter="historyKeyword"
v-model:pagination="pagination"
: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-card-section>
</q-card>
<q-separator color="grey-4" />
</q-header>
<q-page-container>
<q-page class="q-pa-md">
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
<q-space />
<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>
<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>
</template>

View file

@ -165,6 +165,11 @@ const pagination = ref({
rowsPerPage: 10,
});
const historyPagination = ref({
page: 1,
rowsPerPage: 10,
});
const visibleColumns = ref<string[]>([
"field",
"detail",
@ -238,7 +243,6 @@ async function fetchHistoryData(id: string) {
.get(config.API.profileNewAbilityHisByAbilityId(id))
.then(async (res) => {
historyRows.value = res.data.result;
console.log(res.data.result);
})
.catch((err) => {
messageError($q, err);
@ -434,19 +438,6 @@ onMounted(async () => {
>
<q-tooltip>ประวแกไขความสามารถพเศษ</q-tooltip>
</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-tr>
</template>
@ -504,151 +495,185 @@ onMounted(async () => {
</d-table>
<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-card-section class="flex justify-between" style="padding: 0">
<dialog-header
:tittle="dialogStatus == 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'"
:close="closeDialog"
/>
</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">
<div class="col">
<q-input
outlined
class="inputgreen"
dense
bg-color="white"
v-model="specialSkill.field"
label="ด้าน"
hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกด้านความสามารถพิเศษ'}`]"
/>
<q-header>
<q-toolbar>
<dialog-header
:tittle="
dialogStatus == 'edit'
? 'แก้ไขข้อมูลความสามารถพิเศษ'
: 'เพิ่มข้อมูลความสามารถพิเศษ'
"
:close="closeDialog"
/>
</q-toolbar>
<q-separator color="grey-4" />
</q-header>
<q-page-container>
<q-page class="q-pa-md">
<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-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 class="col">
<q-input
outlined
dense
class="inputgreen"
bg-color="white"
v-model="specialSkill.detail"
label="รายละเอียด"
hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
/>
</div>
</div>
<q-input
class="col-12 inputgreen"
outlined
dense
bg-color="white"
v-model="specialSkill.remark"
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-page>
</q-page-container>
<q-footer>
<q-separator color="grey-4" />
<q-toolbar class="fit row wrap justify-end items-start content-start">
<q-btn
dense
unelevated
label="บันทึก"
id="onSubmit"
type="submit"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-toolbar>
</q-footer>
</q-form>
</q-card>
</q-layout>
</q-dialog>
<q-dialog v-model="historyDialog" class="dialog" persistent>
<q-card style="min-width: 70%" class="bg-white">
<q-card-section class="flex justify-between" style="padding: 0">
<dialog-header
tittle="ประวัติแก้ไขความสามารถพิเศษ"
:close="closeHistoryDialog"
/>
</q-card-section>
<q-separator color="grey-4" />
<q-card-section>
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
<q-space />
<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-layout
view="lHh lpr lFf"
container
style="height: 80vh; min-width: 80%"
class="bg-white"
>
<q-header>
<q-toolbar>
<dialog-header
tittle="ประวัติแก้ไขความสามารถพิเศษ"
:close="closeHistoryDialog"
/>
</q-toolbar>
<d-table
ref="table"
:columns="historyColumns"
:rows="historyRows"
row-key="name"
flat
bordered
:paging="true"
dense
:filter="historyKeyword"
v-model:pagination="pagination"
: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-card-section>
</q-card>
<q-separator color="grey-4" />
</q-header>
<q-page-container>
<q-page class="q-pa-md">
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
<q-space />
<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>
<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>
</template>

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { onMounted, reactive, ref, watch } from "vue";
import { useQuasar } from "quasar";
import type { FormBasicinfo } from "@/modules/15_development/interface/request/Main";
@ -40,7 +40,7 @@ onMounted(() => {
});
</script>
<template>
<q-form greedy @submit.prevent @validation-success="onSubmit">
<!-- <q-form greedy @submit.prevent @validation-success="onSubmit"> -->
<div class="row col-12 q-col-gutter-md q-pa-md">
<div class="col-xs-6 col-sm-2 col-md-2">
<datepicker
@ -138,7 +138,7 @@ onMounted(() => {
</div>
</div>
<q-separator />
<!-- <q-separator />
<div class="text-right q-pa-sm">
<q-btn
dense
@ -151,8 +151,8 @@ onMounted(() => {
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</div>
</q-form>
</div> -->
<!-- </q-form> -->
<DialogSelectAgency
v-model:modal="modalDialogSelect"

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import { ref } from "vue";
import { useQuasar } from "quasar";
import { useRouter, useRoute } from "vue-router";
import BasicInfo from "@/modules/15_development/components/BasicInfo.vue";
@ -8,56 +9,81 @@ import ProjectDetail from "@/modules/15_development/components/ProjectDetail.vue
import FollowResult from "@/modules/15_development/components/FollowResult.vue";
import Other from "@/modules/15_development/components/Other.vue";
import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const router = useRouter();
const route = useRoute();
const { showLoader, hideLoader, dialogConfirm } = useCounterMixin();
const title = ref<string>(route.params.id ? "แก้ไข" : "เพิ่ม");
const tab = ref<string>("BasicInfo");
function onSubmit() {
dialogConfirm($q, () => {});
}
</script>
<template>
<div class="toptitle text-dark col-12 row items-center">
<q-btn
flat
round
dense
class="q-mr-sm"
icon="mdi-arrow-left"
color="primary"
@click="router.go(-1)"
/>
{{ `${title}รายการโครงการ/หลักสูตรการฝึกอบรม` }}
</div>
<q-card flat bordered class="col-12">
<q-tabs
v-model="tab"
dense
align="left"
inline-label
class="rounded-borders"
indicator-color="primary"
active-bg-color="teal-1"
active-class="text-primary"
>
<q-tab name="BasicInfo" label="ข้อมูลเบื้องต้น" />
<q-tab name="Target" label="เป้าหมาย" />
<q-tab name="ProjectDetail" label="ลักษณะโครงการ" />
<q-tab name="FollowResult" label="การติดตามการประเมินผล" />
<q-tab name="Other" label="อื่นๆ" />
</q-tabs>
<q-separator />
<div class="q-pa-sm" style="padding: 0px">
<q-tab-panels v-model="tab" animated>
<q-tab-panel style="padding: 0px" name="BasicInfo">
<BasicInfo />
</q-tab-panel>
<q-tab-panel name="Target"> <Target /></q-tab-panel>
<q-tab-panel name="ProjectDetail"> <ProjectDetail /> </q-tab-panel>
<q-tab-panel name="FollowResult"> <FollowResult /> </q-tab-panel>
<q-tab-panel name="Other"> <Other /> </q-tab-panel>
</q-tab-panels>
<q-form greedy @submit.prevent @validation-success="onSubmit">
<div class="toptitle text-dark col-12 row items-center">
<q-btn
flat
round
dense
class="q-mr-sm"
icon="mdi-arrow-left"
color="primary"
@click="router.go(-1)"
/>
{{ `${title}รายการโครงการ/หลักสูตรการฝึกอบรม` }}
<q-space />
<q-btn
dense
unelevated
label="บันทึก"
id="onSubmit"
type="submit"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
<!-- <q-btn unelevated label="บันทึก" color="public" @click="onSubmit">
<q-tooltip>นทกขอม</q-tooltip>
</q-btn> -->
</div>
</q-card>
<q-card flat bordered class="col-12">
<q-tabs
v-model="tab"
dense
align="left"
inline-label
class="rounded-borders"
indicator-color="primary"
active-bg-color="teal-1"
active-class="text-primary"
>
<q-tab name="BasicInfo" label="ข้อมูลเบื้องต้น" />
<q-tab name="Target" label="เป้าหมาย" />
<q-tab name="ProjectDetail" label="ลักษณะโครงการ" />
<q-tab name="FollowResult" label="การติดตามการประเมินผล" />
<q-tab name="Other" label="อื่นๆ" />
</q-tabs>
<q-separator />
<div class="q-pa-sm" style="padding: 0px">
<q-tab-panels v-model="tab" animated>
<q-tab-panel style="padding: 0px" name="BasicInfo">
<BasicInfo />
</q-tab-panel>
<q-tab-panel name="Target"> <Target /></q-tab-panel>
<q-tab-panel name="ProjectDetail"> <ProjectDetail /> </q-tab-panel>
<q-tab-panel name="FollowResult"> <FollowResult /> </q-tab-panel>
<q-tab-panel name="Other"> <Other /> </q-tab-panel>
</q-tab-panels>
</div>
</q-card>
</q-form>
</template>
<style scoped></style>

View file

@ -489,7 +489,8 @@ onMounted(() => {
hide-bottom-space
v-model="formGroupTarget.amount"
label="จำนวน(คน)"
mask="#####"
mask="#"
reverse-fill-mask
:rules="[
(val:string) =>
!!val || `${'กรุณากรอกจำนวน(คน)'}`,
@ -545,7 +546,8 @@ onMounted(() => {
hide-bottom-space
v-model="formGroupRelate.amount"
label="จำนวน(คน)"
mask="#####"
mask="#"
reverse-fill-mask
:rules="[
(val:string) =>
!!val || `${'กรุณากรอกจำนวน(คน)'}`,

View file

@ -47,6 +47,27 @@ const columns = ref<QTableProps["columns"]>([
]);
const visibleColumns = ref<string[]>(["year", "name", "org"]);
const itemDownload = ref<any>([
{
label: "ดาวน์โหลด 1",
value: "",
icon: "mdi-file-pdf-box",
color: "green",
},
{
label: "ดาวน์โหลด 2",
value: "",
icon: "mdi-file-table",
color: "red",
},
{
label: "ดาวน์โหลด 3",
value: "",
icon: "mdi-file-word",
color: "blue",
},
]);
function fetchListProject() {
showLoader();
const data = [
@ -115,11 +136,33 @@ onMounted(() => {
</q-input>
</template>
</datepicker>
<q-btn flat round dense icon="add" color="primary" @click="onClickAddOrView()">
<q-btn
flat
round
dense
icon="add"
color="primary"
@click="onClickAddOrView()"
>
<q-tooltip>เพ</q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-btn flat round color="primary" icon="mdi-download-outline">
<q-menu>
<q-list style="min-width: 100px" dense>
<q-item clickable v-close-popup v-for="items in itemDownload">
<q-item-section avatar>
<q-icon :color="items.color" :name="items.icon" />
</q-item-section>
<q-item-section :class="`text-${items.color}`">{{
items.label
}}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
<q-input
standout
dense