ย้ายตำแหน่ง

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-02-02 14:30:07 +07:00
parent 7112e60b69
commit 48b330b53a
6 changed files with 332 additions and 12 deletions

View file

@ -0,0 +1,264 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import type { QTableProps } from "quasar";
import type {
OrgTree,
PosMaster2,
} from "@/modules/02_organizationalNew/interface/response/organizational";
import type { MovePos } from "@/modules/02_organizationalNew/interface/request/organizational";
import HeaderDialog from "@/components/DialogHeader.vue";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
const $q = useQuasar();
const store = useOrganizational();
const {
showLoader,
hideLoader,
dialogConfirm,
messageError,
dialogMessageNotify,
success,
} = useCounterMixin();
const modal = defineModel<boolean>("modal", { required: true });
const nodeTree = defineModel<OrgTree[]>("nodeTree", { required: true });
const columns = defineModel<QTableProps[]>("columns", {});
const rows = defineModel<PosMaster2[]>("rows", { required: true });
const props = defineProps({
fetchDataTree: {
type: Function,
required: true,
},
type: {
type: String,
required: true,
},
rowId: {
type: String,
required: true,
},
});
const title = ref<string>("ย้ายตำแหน่ง");
const filterTree = ref<string>("");
const filterRef = ref();
const selectedTree = ref<string>("");
const levelTree = ref<number>(0);
const filterTable = ref<string>("");
const selectedFilter = ref<PosMaster2[]>([]);
function resetFilter() {
filterTree.value = "";
filterRef.value.focus();
}
function updateSelected(orgLevel: number) {
levelTree.value = orgLevel;
}
const isDisable = computed(() => {
if (selectedTree.value === "" && selectedFilter.value.length === 0) {
return true;
} else return false;
});
function onClickMovePos() {
if (selectedTree.value === "" || selectedTree.value === null) {
console.log("เลือกหน่วยงาน");
dialogMessageNotify($q, "กรุณาเลือกหน่วยงานที่จะย้ายไป");
} else if (selectedFilter.value.length === 0) {
console.log("เลือกตำแห่นง");
dialogMessageNotify($q, "กรุณาเลือกตำแห่นงที่จะย้าย");
} else {
dialogConfirm(
$q,
async () => {
const position = selectedFilter.value.map((e: PosMaster2) => e.id);
const body: MovePos = {
id: selectedTree.value,
type: levelTree.value,
positionMaster: position,
};
showLoader();
await http
.post(config.API.orgPosMove, body)
.then(() => {
props.fetchDataTree?.(store.draftId);
modal.value = false;
success($q, "ย้ายตำแหน่งสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการย้ายตำแหน่ง",
"ต้องการยืนยันการย้ายตำแหน่งนี้หรือไม่ ?"
);
}
}
watch(
() => modal.value,
() => {
if (modal.value && props.type === "SINGER") {
const data = rows.value.filter((e: PosMaster2) => e.id === props.rowId);
selectedFilter.value = data;
}
}
);
</script>
<template>
<q-dialog v-model="modal" full-width persistent>
<q-card>
<HeaderDialog :tittle="title" :close="() => (modal = false)" />
<q-separator />
<q-card-section class="q-pt-none bg-grey-2 q-pa-md">
<div class="row">
<q-card
class="col-12 col-sm-3 scroll q-pa-sm"
style="max-height: 70vh"
>
<q-input
ref="filterRef"
dense
outlined
v-model="filterTree"
label="ค้นหา"
>
<template v-slot:append>
<q-icon
v-if="filterTree !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template>
</q-input>
<q-tree
class="q-pa-md q-gutter-sm"
dense
default-expand-all
selected-color="primary"
:nodes="nodeTree"
node-key="orgTreeId"
label-key="orgTreeName"
:filter="filterTree"
no-results-label="ไม่พบข้อมูลที่ค้นหา"
no-nodes-label="ไม่มีข้อมูล"
v-model:selected="selectedTree"
>
<template v-slot:default-header="prop">
<!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree-->
<div
class="row items-center q-px-xs q-pt-xs q-gutter-sm"
@click="updateSelected(prop.node.orgLevel)"
>
<div>
<div class="text-weight-medium">
{{ prop.node.orgTreeName }}
</div>
<div class="text-weight-light">
{{ prop.node.orgCode == null ? null : prop.node.orgCode }}
{{
prop.node.orgTreeShortName == null
? null
: prop.node.orgTreeShortName
}}
</div>
</div>
</div>
</template>
</q-tree>
</q-card>
<q-card class="col-12 col-sm-9 q-pa-sm">
<q-toolbar style="padding: 0">
<q-space />
<div>
<q-input outlined dense v-model="filterTable" label="ค้นหา" />
</div>
</q-toolbar>
<d-table
flat
bordered
:rows="rows"
:columns="columns"
row-key="id"
:filter="filterTable"
no-data-label="ไม่มีข้อมูล"
selection="multiple"
v-model:selected="selectedFilter"
>
<template v-slot:header-selection="scope">
<q-checkbox
keep-color
color="primary"
dense
v-model="scope.selected"
/>
</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"
: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>
</q-card>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
dense
unelevated
label="ย้ายตำแหน่ง"
color="public"
@click="onClickMovePos"
class="q-px-md"
:disable="isDisable"
>
<q-tooltip>ายตำแหน</q-tooltip>
</q-btn>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<style scoped></style>

View file

@ -32,6 +32,7 @@ const count = defineModel<number>("count", { required: true });
const nodeId = ref<string>(""); // id Tree
const orgLevel = ref<number>(0); // levelTree
const isLoad = ref<boolean>(false); // loadTable
const selected = ref<string>("");
const nodeData = ref<any>();
const reqMaster = reactive<FilterMaster>({
id: "",
@ -51,14 +52,14 @@ const posMaster = ref<PosMaster2[]>([]);
*/
async function fetchDataTree(id: string) {
showLoader();
// const id =
// store.typeOrganizational === "current" ? store.activeId : store.draftId;
// id &&
await http
.get(config.API.orgByid(id.toString()))
.then((res) => {
const data = res.data.result;
nodeTree.value = data;
selected.value = "";
nodeId.value = "";
})
.catch((err) => {
messageError($q, err);
@ -66,7 +67,6 @@ async function fetchDataTree(id: string) {
.finally(() => {
hideLoader();
});
// console.log(nodeTree.value);
}
/**
@ -172,6 +172,7 @@ watch(
v-model:nodeTree="nodeTree"
v-model:nodeId="nodeId"
v-model:isLoad="isLoad"
v-model:selected="selected"
:fetchDataTree="fetchDataTree"
:fetchDataTable="fetchDataTable"
/>
@ -197,6 +198,7 @@ watch(
<div v-else class="col-12 row items-center">
<TableView
v-if="nodeId !== ''"
v-model:nodeTree="nodeTree"
v-model:orgLevel="orgLevel"
v-model:treeId="nodeId"
v-model:reqMaster="reqMaster"
@ -204,6 +206,7 @@ watch(
v-model:posMaster="posMaster"
:fetchDataTable="fetchDataTable"
:filterKeyword="filterKeyword"
:fetchDataTree="fetchDataTree"
/>
<q-banner v-else class="q-pa-lg col-12 text-center">

View file

@ -86,6 +86,7 @@ const listAdd = ref<ListMenu[]>([
const nodeTEST = defineModel<OrgTree[]>("nodeTree", { default: [] });
const nodeId = defineModel<string>("nodeId", { required: true });
const isLoad = defineModel<boolean>("isLoad", { required: true });
const selected = defineModel<string>("selected", { required: true });
const filter = ref<string>("");
const nodes = ref<Array<OrgTree>>([]);
@ -94,7 +95,7 @@ const lazy = ref(nodes);
const expanded = ref<Array<any>>([]);
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
const noData = ref<string>("ไม่มีข้อมูล");
const selected = ref("");
// const selected = ref("");
const orgLevel = ref<number>(0);
const type = ref<number>(0);
const orgId = ref<string>("");

View file

@ -17,6 +17,7 @@ import type { PosMaster2 } from "@/modules/02_organizationalNew/interface/respon
import DialogFormPosotion from "@/modules/02_organizationalNew/components/DialogFormPosition.vue";
import DialogPositionDetail from "@/modules/02_organizationalNew/components/PositionDetail.vue";
import DialogSort from "@/modules/02_organizationalNew/components/DialogSortPosition.vue";
import DialogMovePos from "@/modules/02_organizationalNew/components/DialogMovePos.vue";
/** importStore*/
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
@ -33,20 +34,22 @@ const props = defineProps({
require: true,
default: () => {},
},
fetchDataTree: {
type: Function,
require: true,
default: () => {},
},
});
const dataSort = ref<Array<any>>([]);
const modalSort = ref<boolean>(false);
const showAllData = ref<boolean>(false);
const currentPage = ref<number>(1);
const nodeTree = defineModel<any>("nodeTree", { required: true });
const orgLevel = defineModel<number>("orgLevel", { required: true });
const treeId = defineModel<string>("treeId", { required: true });
const reqMaster = defineModel<FilterMaster>("reqMaster", { required: true });
const totalPage = defineModel<number>("totalPage", { required: true });
const posMaster = defineModel<PosMaster2[]>("posMaster", { required: true });
const stroe = useOrganizational();
const filter = ref<string>("");
const actionType = ref<string>("");
const listMenu = ref<ListMenu[]>([
{
@ -61,6 +64,12 @@ const listMenu = ref<ListMenu[]>([
type: "DEL",
color: "red",
},
{
label: "ย้ายตำแหน่ง",
icon: "mdi-cursor-move",
type: "MOVE",
color: "positive",
},
{
label: "ดูรายละเอียด",
icon: "mdi-eye",
@ -247,6 +256,15 @@ function onClickDelete(id: string) {
function onClickSort() {
modalSort.value = true;
}
const modalDialogMMove = ref<boolean>(false);
const typeMove = ref<string>("");
function onClickMovePos(id: string, type: string) {
modalDialogMMove.value = !modalDialogMMove.value;
typeMove.value = type;
rowId.value = id;
}
function updatePagination(newPagination: NewPagination) {
reqMaster.value.pageSize = newPagination.rowsPerPage;
reqMaster.value.page = 1;
@ -278,6 +296,17 @@ function updatePagination(newPagination: NewPagination) {
>
<q-tooltip>ดลำด</q-tooltip>
</q-btn>
<q-btn
flat
round
dense
color="positive"
icon="mdi-cursor-move"
@click="onClickMovePos('', 'All')"
>
<q-tooltip>ายตำแหน</q-tooltip>
</q-btn>
</div>
<q-btn flat round dense color="blue-10" icon="save_alt">
@ -395,6 +424,8 @@ function updatePagination(newPagination: NewPagination) {
? onClickPosition('EDIT', props.row.id)
: item.type === 'DEL'
? onClickDelete(props.row.id)
: item.type === 'MOVE'
? onClickMovePos(props.row.id, 'SINGER')
: null
"
>
@ -502,6 +533,10 @@ function updatePagination(newPagination: NewPagination) {
</d-table>
</div>
<!-- รายละเอยดตำแหน -->
<DialogPositionDetail v-model:position-detail="dialogDetail" />
<!-- ตรากำล -->
<DialogFormPosotion
:modal="dialogPosition"
:close="onClickPosition"
@ -513,9 +548,19 @@ function updatePagination(newPagination: NewPagination) {
:fetchDataTable="props.fetchDataTable"
/>
<!-- รายละเอยดตำแหน -->
<DialogPositionDetail v-model:position-detail="dialogDetail" />
<!-- ดลำด -->
<DialogSort v-model:sort-position="modalSort" />
<!-- ายตำแหน -->
<DialogMovePos
v-model:modal="modalDialogMMove"
v-model:nodeTree="nodeTree"
v-model:columns="columns as QTableProps[]"
v-model:rows="posMaster"
:fetchDataTree="props.fetchDataTree"
:type="typeMove"
:rowId="rowId"
/>
</template>
<style lang="scss" scoped>

View file

@ -6,4 +6,10 @@ interface FilterMaster {
pageSize: number; //*จำนวนแถวต่อหน้า
keyword: string; //ข้อความที่ต้องการค้นหา
}
export type { FilterMaster };
interface MovePos {
id: string;
type: number;
positionMaster: string[];
}
export type { FilterMaster, MovePos };