hrms-mgt/src/modules/02_organization/components/StructureOrgMain.vue

208 lines
5.7 KiB
Vue

<script setup lang="ts">
import { ref, onMounted, watch, onBeforeMount } from "vue";
import { useQuasar } from "quasar";
import { OrgChart } from "bma-org-chart";
import "bma-org-chart/org-chart.css";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useStructStore } from "@/modules/02_organization/store/chart";
import avatar from "@/assets/avatar_user.jpg";
import chartData from "@/assets/orgChartData";
const mixin = useCounterMixin();
const store = useOrganizational();
const storeOrg = useStructStore();
const { showLoader, hideLoader, messageError } = mixin;
const $q = useQuasar(); // show dialog
const dataSource = ref(chartData); // ข้อมูล Chart
const rootOrgID = ref(); // org id ของ root ตัวปัจจุบันที่เลือกอยู่
const dataSourceLock = ref(); // ข้อมูลตั้งต้นของ Chart ใช้ให้กดกลับไปที่ home
const chartRef = ref(); // อ้างอิงไปที่ตัว chart
/**
* fetch ข้อมูล Chart โครงสร้าง
*/
async function fetchOrgChart() {
if (rootOrgID.value) {
showLoader();
let urlRequest = config.API.orgChart(rootOrgID.value);
await http
.get(urlRequest)
.then(async (response) => {
if (response.data.result.length > 0) {
const data = await response.data.result;
const updatedData = await Promise.all(data.map(addAvatarToData));
dataSource.value = await updatedData[0];
storeOrg.dataSource = updatedData[0];
if (dataSourceLock.value === undefined)
dataSourceLock.value = dataSource.value;
}
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
}
/**
* map ข้อมูล Chart
* @param item ข้อมูล Chart
*/
async function addAvatarToData(item: any) {
// เพิ่ม avatar ให้กับ item
const updatedItem = {
...item,
// avatar: item.avatar ? await fetchProfile(item.avatar) : avatar,
avatar: avatar,
// ตรวจสอบว่า item มี children หรือไม่
children: item.children
? await Promise.all(item.children.map(addAvatarToData))
: [],
};
return updatedItem;
}
/**
* fetch รูปโปรไฟล์ return ลิงก์ download ไฟล์
* @param path ไฟล์รูป
*/
async function fetchProfile(path: string) {
try {
const res = await http.get(config.API.filefullPath(path));
return res.data.downloadUrl; // คืนค่า URL ของ avatar
} catch (err) {
return avatar; // คืนค่า default avatar ถ้าเกิดข้อผิดพลาด
}
}
/**
* เมื่อมีการคลิกที่ Chart ให้อ่าน ID ของหน่วยงานที่ถูกคลิก แล้วดึงข้อมูล Chart ของหน่วยงานนั้น ๆ จาก API
* @param data
*/
async function refreshChart(data: any) {
if (data.value !== undefined) rootOrgID.value = data.value;
else rootOrgID.value = data;
if (rootOrgID.value !== 0) await fetchOrgChart();
if (data.value !== undefined) data.value = 0;
}
/**
* โหลด Chart รูป
*/
function savePNG() {
chartRef.value.savePNG();
}
/**
* โหลด Chart PDF
*/
function savePDF() {
chartRef.value.savePDF();
}
watch(
[() => store.typeOrganizational, () => store.historyId],
([new1], [old1]) => {
if (new1 === "old" && old1 !== "old") {
store.historyId = "";
}
rootOrgID.value =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: store.historyId;
fetchOrgChart();
}
);
onMounted(async () => {
rootOrgID.value =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: store.historyId;
fetchOrgChart();
});
onBeforeMount(() => {
storeOrg.dataSource = undefined;
});
</script>
<template>
<!-- <div class="toptitle text-dark col-12 row items-center">แผนภองคกร</div> -->
<div class="text-dark">
<q-card class="col-12 q-mt-sm">
<div class="q-pa-sm">
<q-btn flat round color="primary" @click="savePNG()" icon="mdi-image">
<q-tooltip> ดาวนโหลด PNG </q-tooltip>
</q-btn>
<q-btn
flat
round
color="red-7"
@click="savePDF()"
icon="mdi-file-pdf-box"
>
<q-tooltip> ดาวนโหลด PDF </q-tooltip>
</q-btn>
</div>
<q-separator />
<div style="overflow-x: auto; overflow-y: auto" class="q-pt-md">
<OrgChart
v-if="storeOrg.dataSource"
style="height: 70vh"
ref="chartRef"
class="org"
:dataSource="dataSource"
@onElementClick="refreshChart"
/>
</div>
</q-card>
</div>
</template>
<style>
.org .section-list {
padding: 15px !important;
}
.org .section-list .column-content .header {
font-size: 1rem;
line-height: 1.2rem;
font-weight: 500 !important;
}
.org .section-list .column-content .subheader {
font-weight: 500 !important;
}
.org .section-list .column-content .caption {
font-size: 0.9rem;
line-height: 1.2rem;
font-weight: 400 !important;
}
.org .element-container .column-content p {
padding-top: 3px !important;
}
.org .element-container .column-side .side-button {
background-size: 14px;
}
</style>