Merge branch 'develop' into devTee

This commit is contained in:
setthawutttty 2024-02-09 11:54:30 +07:00
commit 7623a1e762
7 changed files with 487 additions and 428 deletions

View file

@ -37,6 +37,6 @@ export default {
/**ครองตำแหน่ง */
orgSearchProfile: `${orgProfile}/search`,
orgProfile: `${orgProfile}`,
orgDeleteProfile: (id: string) => `${orgProfile}/delete/${id}`,
orgProfile: `${orgPos}/profile`,
orgDeleteProfile: (id: string) => `${orgPos}/profile/delete/${id}`,
};

View file

@ -588,11 +588,10 @@ async function emitSearch(keyword: string, typeSelect: string) {
:close="close"
/>
<q-separator />
<q-card-section class="q-pa-sm">
<div class="row q-col-gutter-sm">
<div class="col-12">
<form @submit.prevent="validateForm">
<form @submit.prevent="validateForm">
<q-card-section class="q-pa-sm">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-card bordered class="col-12" style="border: 1px solid #d6dee1">
<div
class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
@ -711,190 +710,189 @@ async function emitSearch(keyword: string, typeSelect: string) {
<q-btn
:icon="
!isPosition
? 'mdi-arrow-right-drop-circle'
: 'mdi-arrow-down-drop-circle'
? 'mdi-menu-right'
: 'mdi-menu-down'
"
flat
round
color="teal"
class="q-ml-sm"
label="เพิ่มตำแหน่ง"
@click="isPosition = !isPosition"
><q-tooltip>{{
!isPosition
? "เลือกตำแหน่งที่ต้องการเพิ่ม"
: "ปิดหน้าต่าง"
? "คลิกเพื่อแสดงส่วนของการเพิ่มตำแหน่ง"
: "ปิดหน้าต่างการเพิ่มตำแหน่ง"
}}</q-tooltip></q-btn
>
<q-space />
<q-checkbox
keep-color
v-model="succession"
label="สืบทอดตำแหน่ง"
color="primary"
>
<q-tooltip
>บทอดตำแหน</q-tooltip
>
<q-tooltip>บทอดตำแหน</q-tooltip>
</q-checkbox>
<q-space />
<q-btn type="submit" :label="`บันทึก`" color="public" />
</q-card-actions>
</q-card>
</form>
</div>
</div>
</div>
<div v-if="isPosition" class="row q-col-gutter-sm q-mt-sm">
<div class="col-12">
<q-card bordered class="col-12" style="border: 1px solid #d6dee1">
<div class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md">
เลอกตำแหนงทองการเพ
<q-btn
icon="mdi-plus"
flat
round
color="teal"
@click="() => (modalAdd = true)"
><q-tooltip>สรางตำแหน</q-tooltip></q-btn
<div v-if="isPosition" class="row q-col-gutter-sm q-mt-sm">
<div class="col-12">
<q-card bordered class="col-12" style="border: 1px solid #d6dee1">
<div
class="col-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
</div>
<div class="col-12"><q-separator /></div>
<div class="q-pa-sm">
<div class="row col-12 q-col-gutter-sm items-start">
<div class="col-12 col-sm-6 col-md-3">
<q-select
label="ค้นหาจาก"
v-model="type"
:options="optionFilter"
emit-value
dense
map-options
outlined
option-label="name"
option-value="id"
/>
</div>
<div class="col-12 col-sm-6 col-md-6">
<q-input
ref="searchRef"
:class="inputEdit(isReadonly)"
v-model="search"
outlined
clearable
dense
lazy-rules
label="คำค้น"
hide-bottom-space
:rules="[(val) => !!val || `กรุณากรอกคำค้น`]"
/>
</div>
<div class="col-12 col-sm-6 col-md-3">
<q-btn
color="primary"
icon="search"
label="ค้นหา"
class="full-width q-pa-sm"
@click="searchInput()"
>
</q-btn>
</div>
</div>
<div class="full-width q-mt-sm">
<d-table
ref="table"
:columns="columns"
:rows="rowsPositionSelect"
row-key="id"
เลอกตำแหนงทองการเพ
<q-btn
icon="mdi-plus"
flat
bordered
:paging="true"
dense
class="custom-header-table"
:visible-columns="visibleColumns"
round
color="teal"
@click="() => (modalAdd = true)"
><q-tooltip>สรางตำแหน</q-tooltip></q-btn
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
style="color: #000000; font-weight: 500"
>
<span class="text-weight-medium">{{
col.label
}}</span>
</q-th>
<q-th auto-width></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.name"
:props="props"
@click="addPosition(props.row)"
>
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
flat
dense
icon="mdi-dots-vertical"
class="q-pa-none q-ml-xs"
color="grey-13"
>
<q-menu anchor="bottom middle" self="top middle">
<q-list
dense
v-for="(item, index) in listMenu"
:key="index"
>
<q-item
clickable
v-close-popup
@click="
item.type === 'copy'
? copyDetiail(props.row)
: deletePos(props.row.id)
"
>
<q-item-section avatar>
<q-icon
:color="item.color"
:name="item.icon"
size="sm"
/>
</q-item-section>
<q-item-section>{{
item.label
}}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
</div>
</div>
</q-card>
<div class="col-12"><q-separator /></div>
<div class="q-pa-sm">
<div class="row col-12 q-col-gutter-sm items-start">
<div class="col-12 col-sm-6 col-md-3">
<q-select
label="ค้นหาจาก"
v-model="type"
:options="optionFilter"
emit-value
dense
map-options
outlined
option-label="name"
option-value="id"
/>
</div>
<div class="col-12 col-sm-6 col-md-6">
<q-input
ref="searchRef"
:class="inputEdit(isReadonly)"
v-model="search"
outlined
clearable
dense
lazy-rules
label="คำค้น"
hide-bottom-space
:rules="[(val) => !!val || `กรุณากรอกคำค้น`]"
/>
</div>
<div class="col-12 col-sm-6 col-md-3">
<q-btn
color="primary"
icon="search"
label="ค้นหา"
class="full-width q-pa-sm"
@click="searchInput()"
>
</q-btn>
</div>
</div>
<div class="full-width q-mt-sm">
<d-table
ref="table"
:columns="columns"
:rows="rowsPositionSelect"
row-key="id"
flat
bordered
:paging="true"
dense
class="custom-header-table"
:visible-columns="visibleColumns"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
style="color: #000000; font-weight: 500"
>
<span class="text-weight-medium">{{
col.label
}}</span>
</q-th>
<q-th auto-width></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.name"
:props="props"
@click="addPosition(props.row)"
>
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
flat
dense
icon="mdi-dots-vertical"
class="q-pa-none q-ml-xs"
color="grey-13"
>
<q-menu anchor="bottom middle" self="top middle">
<q-list
dense
v-for="(item, index) in listMenu"
:key="index"
>
<q-item
clickable
v-close-popup
@click="
item.type === 'copy'
? copyDetiail(props.row)
: deletePos(props.row.id)
"
>
<q-item-section avatar>
<q-icon
:color="item.color"
:name="item.icon"
size="sm"
/>
</q-item-section>
<q-item-section>{{
item.label
}}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
</div>
</div>
</q-card>
</div>
</div>
</div>
</q-card-section>
<!-- <q-separator />
<q-card-actions align="right" class="bg-white text-teal">
<q-btn type="submit" :label="`บันทึก`" color="public" />
</q-card-actions> -->
</q-card-section>
<q-separator />
<q-card-actions align="right" class="bg-white text-teal">
<q-btn type="submit" :label="`บันทึก`" color="public" />
</q-card-actions>
</form>
</q-card>
</q-dialog>
<DialogAddPosition

View file

@ -1,68 +1,72 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importType*/
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
import DialogHeader from "@/components/DialogHeader.vue";
import type { Position } from "@/modules/02_organizationalNew/interface/index/organizational";
import type { DataOption } from "@/modules/02_organizationalNew/interface/index/Main";
import type {
Position,
SeaechResult,
FormPositionFilter,
} from "@/modules/02_organizationalNew/interface/index/organizational";
import type {
DataOption,
NewPagination,
} from "@/modules/02_organizationalNew/interface/index/Main";
import type {
OptionType,
OptionExecutive,
OptionLevel,
SelectPerson,
TypePos,
} from "@/modules/02_organizationalNew/interface/response/organizational";
interface FormDetailPosition {
positionNo: string;
positionType: string;
positionLevel: string;
personal: string;
position: string;
status: string;
}
interface SeaechResult {
id: string;
citizenId: string;
name: string;
posTypeName: string;
posLevelName: string;
}
/** importCompoonents*/
import DialogHeader from "@/components/DialogHeader.vue";
const isReadonly = ref<boolean>(false); //
const isDisValidate = ref<boolean>(false);
const executiveOpsMain = ref<DataOption[]>([]);
const typeOpsMain = ref<DataOption[]>([]);
const levelOpsMain = ref<DataOption[]>([]);
const typeOps = ref<DataOption[]>([]);
const levelOps = ref<DataOption[]>([]);
const dataLevel = ref<any>();
const selected = ref<string[]>([]);
const isSit = ref<boolean>(false);
const executiveOps = ref<DataOption[]>([]);
const store = useOrganizational();
/** import*Store*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
/** use*/
const $q = useQuasar();
const { dialogConfirm, showLoader, success, hideLoader, messageError } =
useCounterMixin();
const store = useOrganizational();
const {
dialogConfirm,
showLoader,
success,
hideLoader,
messageError,
dialogMessageNotify,
} = useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
// const modal = ref<boolean>(true);
const props = defineProps({
fetchActive: {
type: Function,
require: true,
},
dataDetailPos: { type: Object, require: true },
fetchDataTable: {
type: Function,
required: true,
},
});
const row = ref<Position[]>([]);
const rowResult = ref<SeaechResult[]>([]);
const formData = reactive<FormDetailPosition>({
const isReadonly = ref<boolean>(false); //
const isDisValidate = ref<boolean>(false);
const typeOpsMain = ref<DataOption[]>([]);
const levelOpsMain = ref<DataOption[]>([]);
const typeOps = ref<DataOption[]>([]);
const levelOps = ref<DataOption[]>([]);
const dataLevel = ref<TypePos[]>([]);
const selected = ref<Position[]>([]);
const isSit = ref<boolean>(false);
const formData = reactive<FormPositionFilter>({
positionNo: "", //*
positionType: "", //*
positionLevel: "", //*
@ -71,6 +75,7 @@ const formData = reactive<FormDetailPosition>({
status: "",
});
/** Table*/
const visibleColumnsResult = ref<String[]>([
"no",
"citizenId",
@ -78,7 +83,6 @@ const visibleColumnsResult = ref<String[]>([
"posTypeName",
"posLevelName",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -209,11 +213,15 @@ const columnsResult = ref<QTableProps["columns"]>([
style: "font-size: 14px",
},
]);
const row = ref<Position[]>([]);
const rowResult = ref<SeaechResult[]>([]);
/** function closePopup*/
function close() {
modal.value = false;
}
/** function เรียกข้อมูลประเภทตำแหน่ง*/
async function fetchType() {
showLoader();
await http
@ -234,26 +242,6 @@ async function fetchType() {
});
}
/** function เรียกรายการตำแหน่งทางการบริหาร */
async function fetchExecutive() {
showLoader();
await http
.get(config.API.orgPosExecutive)
.then((res) => {
executiveOpsMain.value = res.data.result.map((e: OptionExecutive) => ({
id: e.id,
name: e.posExecutiveName,
}));
executiveOps.value = executiveOpsMain.value;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
@ -265,6 +253,105 @@ function inputEdit(val: boolean) {
};
}
/** function เรียกข้แมูลระดับตำแหน่ง*/
function updateSelectType(val: string) {
const listLevel: any = dataLevel.value.find((e: TypePos) => e.id === val);
levelOpsMain.value = listLevel?.posLevels.map((e: OptionLevel) => ({
id: e.id,
name: e.posLevelName,
}));
levelOps.value = levelOpsMain.value;
formData.positionLevel = "";
}
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function validateForm() {
if (selected.value.length === 0) {
dialogMessageNotify($q, "กรุณาเลือกรายการตำแหน่ง");
} else if (selectedProfile.value.length === 0) {
dialogMessageNotify($q, "กรุณาเลือกคนครอง");
} else {
onSubmit();
}
}
/** function ยืนยันการบันทึกข้อมูล */
function onSubmit() {
dialogConfirm(
$q,
() => {
const body = {
posMaster: props.dataDetailPos?.id, //*id
position: selected.value[0]?.id, //*id
profileId: selectedProfile.value[0]?.id, //*id profile
isSit: isSit.value, //*
};
showLoader();
http
.post(config.API.orgProfile, body)
.then(() => {
props.fetchDataTable?.(store.treeId, store.level, false);
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
modal.value = await false;
close();
hideLoader();
});
},
"ยืนยันการเลือกคนครอง",
"ต้องการยืนยันการเลือกคนครองตำแหน่งนี้ใช่หรือไม่?"
);
}
const page = ref<number>(1);
const pageSize = ref<number>(10);
const totalPage = ref<number>(0);
const selectedProfile = ref<SeaechResult[]>([]);
/** functiuon ค้นหาคนครอง */
async function searchData() {
showLoader();
const reqBody = {
posTypeId: formData.positionType, // id
posLevelId: formData.positionLevel, // id
position: formData.position, //
page: page.value, //*
pageSize: pageSize.value, //*
keyword: formData.personal, //
};
await http
.post(config.API.orgSearchProfile, reqBody)
.then((res) => {
totalPage.value = Math.ceil(res.data.result.total / pageSize.value);
const list = res.data.result.data.map((e: SelectPerson) => ({
id: e.id,
citizenId: e.citizenId,
name: `${e.prefix + e.firstName + " " + e.lastName}`,
posTypeName: e.posType ?? "-",
positionName: e.position ?? "-",
posLevelName: e.posLevel ?? "-",
}));
rowResult.value = list;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/** function update PageSize*/
function updatePagination(newPagination: NewPagination) {
pageSize.value = newPagination.rowsPerPage;
page.value = 1;
}
/** function เคลียร์Form*/
function clearForm() {
formData.positionType = "";
formData.positionLevel = "";
@ -272,15 +359,24 @@ function clearForm() {
formData.position = "";
row.value = [];
rowResult.value = [];
selected.value = [];
selectedProfile.value = [];
isSit.value = false;
}
/** function เคลียร์ตำแหน่ง*/
function clearPosition() {
formData.positionType = "";
formData.positionLevel = "";
}
/** callback function ทำงานเมื่อเปิด popup*/
watch(
() => modal.value,
() => {
if (modal.value == true) {
clearForm();
fetchType();
fetchExecutive();
if (props.dataDetailPos) {
formData.positionNo = props.dataDetailPos.posMasterNo;
@ -307,128 +403,10 @@ watch(
}
);
function updateSelectType(val: string) {
const listLevel = dataLevel.value.find((e: any) => e.id === val);
levelOpsMain.value = listLevel.posLevels.map((e: OptionLevel) => ({
id: e.id,
name: e.posLevelName,
}));
levelOps.value = levelOpsMain.value;
formData.positionLevel = "";
}
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function validateForm() {
// const hasError = [];
// for (const key in objectRef) {
// if (Object.prototype.hasOwnProperty.call(objectRef, key)) {
// const property = objectRef[key];
// if (property.value && typeof property.value.validate === "function") {
// const isValid = property.value.validate();
// hasError.push(isValid);
// }
// }
// }
// if (hasError.every((result) => result === true)) {
onSubmit();
// } else {
// }
}
/** ฟังชั่น บันทึก */
function onSubmit() {
dialogConfirm(
$q,
() => {
console.log("ตำแหน่ง==>", selected.value);
console.log("ทับที่==>", isSit);
// showLoader();
// http
// .post(config.API.createOrganization, formData)
// .then((res) => {
// status.value = true;
// store.typeOrganizational = "draft";
// store.draftId = res.data.result.id;
// success($q, "");
// // props.fetchActive?.();
// })
// .catch((err) => {
// messageError($q, err);
// })
// .finally(async () => {
// modal.value = await false;
// await close();
// await hideLoader();
// });
},
"ยืนยันการเลือกคนครอง",
"ต้องการยืนยันการเลือกคนครองตำแหน่งนี้ใช่หรือไม่?"
);
}
/** เมื่อ enter ให้ทำการ ค้นหาข้อมูล */
const page = ref<number>(1);
const pageSize = ref<number>(20);
async function searchData() {
showLoader();
console.log(formData);
const reqBody = {
posTypeId: formData.positionType, // id
posLevelId: formData.positionLevel, // id
position: formData.position, //
page: page.value, //*
pageSize: pageSize.value, //*
keyword: formData.personal, //
};
await http
.post(config.API.orgSearchProfile, reqBody)
.then((res) => {
console.log(res);
const list = res.data.result.data.map((e: any) => ({
id: e.id,
citizenId: e.citizenId,
name: `${e.prefix + e.firstName + e.lastName}`,
posTypeName: e.posType ?? "-",
positionName: e.position ?? "-",
posLevelName: e.posLevel ?? "-",
}));
rowResult.value = list;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
// const data = [
// {
// id: "test1",
// citizenId: "test1",
// name: "test1",
// posTypeName: "test1",
// positionName: "test1",
// posLevelName: "test1",
// },
// {
// id: "test2",
// citizenId: "test2",
// name: "test2",
// posTypeName: "test2",
// positionName: "test2",
// posLevelName: "test2",
// },
// ];
// rowResult.value = data;
// props.fetchListDisciplinary?.();
}
function clearPosition() {
formData.positionType = "";
formData.positionLevel = "";
}
/** callback function ทำงานการค้นหาข้อมุลคนครองเมื่อมีการ update Pagination*/
watch([() => page.value, () => pageSize.value], () => {
searchData();
});
</script>
<template>
@ -461,70 +439,66 @@ function clearPosition() {
</div>
<div class="col-12"><q-separator /></div>
<div class="row q-col-gutter-sm q-pa-sm">
<div class="col-12">
<d-table
flat
:columns="columns"
:rows="row"
row-key="id"
dense
hide-pagination
class="custom-header-table"
selection="single"
v-model:selected="selected"
>
<template v-slot:header-selection="scope">
<q-checkbox
keep-color
color="primary"
dense
v-model="scope.checkBox"
/>
</template>
<template v-slot:header="props">
<q-tr :props="props">
<q-th class="text-center"> </q-th>
<div class="q-pa-sm col-12">
<d-table
flat
:columns="columns"
:rows="row"
row-key="id"
dense
hide-pagination
class="custom-header-table"
selection="single"
v-model:selected="selected"
>
<template v-slot:header-selection="scope">
<q-checkbox
keep-color
color="primary"
dense
v-model="scope.checkBox"
/>
</template>
<template v-slot:header="props">
<q-tr :props="props">
<q-th class="text-center"> </q-th>
<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">
<td class="text-center">
<q-checkbox
keep-color
color="primary"
dense
v-model="props.selected"
/>
</td>
<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 class="text-center">
<q-checkbox
keep-color
color="primary"
dense
v-model="props.selected"
/>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else>
{{ col.value }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
</div>
<div v-else>
{{ col.value }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
</div>
</q-card>
@ -653,16 +627,22 @@ function clearPosition() {
/>
<div class="col-12">
<d-table
ref="table"
flat
:columns="columnsResult"
:rows="rowResult"
row-key="id"
dense
hide-pagination
class="custom-header-table"
:paging="true"
:rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination"
selection="single"
v-model:selected="selectedProfile"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width />
<q-th
v-for="col in props.cols"
:key="col.name"
@ -676,6 +656,14 @@ function clearPosition() {
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td>
<q-checkbox
keep-color
color="primary"
dense
v-model="props.selected"
/>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
@ -691,6 +679,17 @@ function clearPosition() {
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="page"
active-color="primary"
color="dark"
:max="totalPage"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</d-table>
</div>
</div>

View file

@ -322,23 +322,27 @@ function openSelectPerson(data: DataPosition[]) {
}
/** ลบคนครอง */
function removePerson(data: DataPosition[]) {
function removePerson(id: string) {
dialogRemove(
$q,
async () => {
showLoader();
// await http
// .delete(config.API.orgPosMasterById(id))
// .then(() => {
// success($q, "");
// props.fetchDataTable?.(reqMaster.value.id, reqMaster.value.type, false);
// })
// .catch((err) => {
// messageError($q, err);
// })
// .finally(() => {
hideLoader();
// });
await http
.post(config.API.orgDeleteProfile(id))
.then(() => {
success($q, "ลบข้อมูลสำเร็จ");
props.fetchDataTable?.(
reqMaster.value.id,
reqMaster.value.type,
false
);
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการลบคนครอง",
"ต้องการยืนยันการลบคนครองนี้ใช่หรือไม่?"
@ -520,7 +524,7 @@ function removePerson(data: DataPosition[]) {
"
clickable
v-close-popup
@click="removePerson(props.row)"
@click="removePerson(props.row.id)"
>
<q-item-section>
<div class="row items-center">
@ -678,6 +682,7 @@ function removePerson(data: DataPosition[]) {
<DialogSelectPerson
v-model:modal="modalSelectPerson"
:dataDetailPos="dataDetailPos"
:fetchDataTable="props.fetchDataTable"
/>
</template>

View file

@ -81,4 +81,27 @@ interface DataTree {
children?: DataTree[];
}
export type { DataPosition, Position, FormDetailPosition, DataTree };
interface SeaechResult {
id: string;
citizenId: string;
name: string;
posTypeName: string;
posLevelName: string;
}
interface FormPositionFilter {
positionNo: string;
positionType: string;
positionLevel: string;
personal: string;
position: string;
status: string;
}
export type {
DataPosition,
Position,
FormDetailPosition,
DataTree,
SeaechResult,
FormPositionFilter,
};

View file

@ -156,6 +156,30 @@ interface HistoryPos {
posMasterNoSuffix: string; //Suffix หลังเลขที่ตำแหน่ง เช่น ช.
}
interface SelectPerson {
citizenId: string;
firstName: string;
id: string;
lastName: string;
posLevel: string;
posType: string;
position: string;
prefix: string;
}
interface PosLevels {
id: string;
posLevelAuthority: null;
posLevelName: string;
posLevelRank: number;
}
interface TypePos {
id: string;
PosLevels: PosLevels[];
posTypeName: string;
posTypeRank: number;
}
export type {
DataActive,
OrgTree,
@ -170,4 +194,7 @@ export type {
Position2,
SumPosition,
HistoryPos,
SelectPerson,
TypePos,
};

View file

@ -452,8 +452,15 @@ watch(posTypeId, () => {
lazy-rules
borderless
class="col-12 bg-white q-ma-md"
:rules="[(val) => val.length > 0 || 'กรุณากรอกเลขประจำตัวประชาชน']"
:rules="[
(val: string) => !!val || `${'กรุณากรอกเลขประจำตัวประชาชน'}`,
(val: string) =>
val.length >= 13 ||
`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,
]"
maxlength="13"
hide-bottom-space
mask="#############"
/>
<q-input
ref="positionRef"