hrms-mgt/src/modules/01_metadataNew/components/position/01ListPosition.vue

410 lines
10 KiB
Vue

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useQuasar } from "quasar";
import type { DataOption } from "@/modules/01_metadataNew/interface/index/Main";
import type { QTableProps } from "quasar";
import DialogAddPosition from "@/modules/01_metadataNew/components/position/DialogAddPosition.vue";
interface FormPositionSelect {
positionId: string;
posTypeId: string;
positionName: string;
positionField: string;
positionType: string;
positionLevel: string;
positionExecutive: string;
positionExecutiveField: string;
positionArea: string;
}
interface ListMenu {
label: string;
icon: string;
type: string;
color: string;
}
interface OptionLevel {
id: string;
posLevelName: string;
}
interface RowDetailPositions {
id: string;
positionId: string;
positionName: string;
positionField: string;
positionType: string;
positionLevel: string;
positionExecutive: string;
positionExecutiveField: string;
positionArea: string;
posTypeId: string;
posLevelId: string;
posExecutiveId: string;
}
const modalAddPosition = ref<boolean>(false);
const levelOpsMain = ref<DataOption[]>([]);
const dataLevel = ref<any>();
const levelOps = ref<DataOption[]>([]);
const formPositionSelect = reactive<FormPositionSelect>({
positionId: "",
posTypeId: "",
positionName: "",
positionField: "",
positionType: "",
positionLevel: "",
positionExecutive: "",
positionExecutiveField: "",
positionArea: "",
});
const rows = ref<RowDetailPositions[]>([]);
const listMenu = ref<ListMenu[]>([
{
label: "คัดลอก",
icon: "mdi-content-copy",
type: "copy",
color: "blue-6",
},
{
label: "ลบ",
icon: "delete",
type: "remove",
color: "red",
},
]);
const columns = ref<QTableProps["columns"]>([
{
name: "no",
align: "left",
label: "ลำดับ",
sortable: false,
field: "no",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "positionName",
align: "left",
label: "ตำแหน่งในสายงาน",
sortable: true,
field: "positionName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "positionField",
align: "left",
label: "สายงาน",
sortable: true,
field: "positionField",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posTypeName",
align: "left",
label: "ประเภทตำเเหน่ง",
sortable: true,
field: "posTypeName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posLevelName",
align: "left",
label: "ระดับตำแหน่ง",
sortable: true,
field: "posLevelName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posExecutiveName",
align: "left",
label: "ตำแหน่งทางการบริหาร",
sortable: true,
field: "posExecutiveName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "positionExecutiveField",
align: "left",
label: "ด้านทางการบริหาร",
sortable: true,
field: "positionExecutiveField",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "positionArea",
align: "left",
label: "ด้าน/สาขา",
sortable: true,
field: "positionArea",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
const visibleColumns = ref<string[]>([
"no",
"positionName",
"positionField",
"posTypeName",
"posLevelName",
"posExecutiveName",
"positionExecutiveField",
"positionArea",
]);
const $q = useQuasar();
const rowsPositionSelect = ref<RowDetailPositions[]>([]);
const mixin = useCounterMixin();
const {
dialogConfirm,
showLoader,
hideLoader,
messageError,
success,
dialogRemove,
} = mixin;
/** input ค้นหา */
const searchRef = ref<any>(null);
const search = ref<string>("");
const type = ref<string>("positionName");
const isReadonly = ref<boolean>(false); // อ่านได้อย่างเดียว
const optionFilter = ref<DataOption[]>([
{ id: "positionName", name: "ตำแหน่งในสายงาน" },
{ id: "positionField", name: "สายงาน" },
{ id: "positionType", name: "ประเภทตำแหน่ง" },
{ id: "positionLevel", name: "ระดับตำแหน่ง" },
{ id: "positionExecutive", name: "ตำแหน่งทางการบริหาร" },
{ id: "positionExecutiveField", name: "ด้านทางการบริหาร" },
{ id: "positionArea", name: "ด้าน/สาขา" },
]);
/**
* คัดลอกข้อมูล
* @param data ข้อมูลตำแหน่ง
*/
function copyDetiail(data: RowDetailPositions) {
formPositionSelect.positionId = data.id;
formPositionSelect.posTypeId = data.posTypeId;
formPositionSelect.positionName = data.positionName;
formPositionSelect.positionField = data.positionField;
formPositionSelect.positionType = data.posTypeId;
formPositionSelect.positionLevel = data.posLevelId;
formPositionSelect.positionExecutive = data.posExecutiveId;
formPositionSelect.positionExecutiveField = data.positionExecutiveField;
formPositionSelect.positionArea = data.positionArea;
modalAddPosition.value = true
}
/**
* ส่งค่า css ออกไปตามเงื่อนไข
* @param val true/false
*/
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
async function searchInput() {
searchRef.value.validate();
if (!searchRef.value.hasError) {
showLoader();
await http
.get(
config.API.orgPosPosition +
`?keyword=${search.value}&type=${type.value}`
)
.then((res) => {
rowsPositionSelect.value = res.data.result;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
}
function addPosition(data: RowDetailPositions) {
const isIdExist = rows.value.some((item: any) => item.id === data.id);
if (!isIdExist) {
rows.value = [data, ...rows.value];
}
}
function deletePos(id: string) {
dialogRemove($q, () => {
showLoader();
http
.delete(config.API.orgPosPositionById(id))
.then(() => {
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
searchInput();
hideLoader();
});
});
}
function popupAdd() {
modalAddPosition.value = true;
}
</script>
<template>
<div class="row col-12 q-mb-sm">
<div class="col-12 col-md-5">
<q-btn
id="addComplaints"
for="addComplaints"
size="12px"
flat
round
color="primary"
icon="mdi-plus"
@click="popupAdd()"
><q-tooltip>เพมตำเเหน </q-tooltip></q-btn
>
</div>
<q-space />
<div class="row col-12 col-md-7 q-col-gutter-sm justify-start">
<div class="col-12 col-sm-6 col-md-4">
<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-4">
<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-4">
<q-btn
color="primary"
icon="search"
label="ค้นหา"
class="full-width q-pa-sm"
@click="searchInput()"
>
</q-btn>
</div>
</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>
<DialogAddPosition
v-model:add-position="modalAddPosition"
v-model:form-data="formPositionSelect"
/>
</template>