UI ตัวชี้วัดตามแผน

This commit is contained in:
oat_dev 2024-04-18 13:41:42 +07:00
parent 0dba62fb43
commit d7f0a31e69
2 changed files with 500 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import IndicatorByPlan from "@/modules/14_KPI/components/indicatorByPlan/indicatorByPlan.vue";
const $q = useQuasar();
const router = useRouter();
@ -36,6 +37,9 @@ onMounted(() => {});
/>
{{ `${title}ตัวชี้วัดตามแผนฯ` }}
</div>
<q-card flat bordered>
<IndicatorByPlan />
</q-card>
</template>
<style scoped></style>

View file

@ -0,0 +1,496 @@
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import config from "@/app.config";
import { QForm, useQuasar } from "quasar";
import http from "@/plugins/http";
import { usePositionEmp } from "@/modules/16_positionEmployee/store/organizational";
const store = usePositionEmp();
const mixin = useCounterMixin();
const $q = useQuasar();
const {
dialogRemove,
dialogConfirm,
showLoader,
hideLoader,
messageError,
success,
date2Thai,
} = mixin;
const planData = reactive<any>({
year: null,
});
const filter = ref<string>("");
const filterAgency = ref<string>("");
const roundOp = ref<any[]>([
{ id: "APRIL", name: "เมษายน" },
{ id: "OCTOBER", name: "ตุลาคม" },
]);
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
const noData = ref<string>("ไม่มีข้อมูล");
const expandedPlan = ref<Array<string | null>>([]);
const expandedAgency = ref<Array<string | null>>([]);
const nodeplan = ref<any>([]);
const nodeAgency = ref<any>([]);
const nodeId = ref<string>("");
async function onSubmit() {
dialogConfirm(
$q,
async () => {},
"ยืนยันการบันทึกข้อมูล",
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
);
}
function fetchTree() {
showLoader();
http
.get(config.API.devStrategy)
.then((res) => {
const data = res.data.result;
nodeplan.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
async function fetchDataTree(id: string) {
showLoader();
await http
.get(config.API.orgByid(id.toString()))
.then((res) => {
const data = res.data.result;
nodeAgency.value = data;
store.treeId = "";
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
async function fetchOrganizationActive() {
showLoader();
await http
.get(config.API.activeOrganization)
.then((res) => {
const data = res.data.result;
if (data) {
store.fetchDataActive(data);
}
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
function updateSelected(data: any) {
planData.strategyChildPlannedId = data.id;
planData.strategyChildPlannedNode = data.level;
}
onMounted(() => {
// fetchData();
fetchTree();
fetchOrganizationActive();
setTimeout(async () => {
store.activeId && (await fetchDataTree(store.activeId));
}, 200);
});
</script>
<template>
<q-form @submit.prevent greedy @validation-success="onSubmit()">
<div>
<div class="row q-col-gutter-md q-pa-md">
<div class="col-8">
<q-input
outlined
v-model="planData.tree"
label="หน่วยงาน/ส่วนราชการ"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'หน่วยงาน/ส่วนราชการ'}`]"
hide-bottom-space
/>
</div>
<div class="col-2">
<q-select
dense
outlined
v-model="planData.round"
:options="roundOp"
label="รอบการประเมิน"
hide-bottom-space
option-label="name"
option-value="id"
map-options
emit-value
lazy-rules
class="inputgreen"
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกรอบการประเมิน'}`,
]"
/>
</div>
<div class="col-2">
<datepicker
menu-class-name="modalfix"
v-model="planData.year"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
@update:modelValue="planData.year"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
lazy-rules
outlined
class="inputgreen"
clearable
@clear="() => (planData.year = null)"
hide-bottom-space
:model-value="!!planData.year ? planData.year + 543 : null"
:label="`${'ปีงบประมาณ'}`"
@update:modelValue="planData.year = null"
>
</q-input>
</template>
</datepicker>
</div>
<div class="col-3">
<q-input
outlined
v-model="planData.Data1"
label="รหัสตัวชี้วัด"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกรหัสตัวชี้วัด'}`]"
hide-bottom-space
/>
</div>
<div class="col-6">
<q-input
outlined
v-model="planData.Data2"
label="ชื่อตัวชี้วัด"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกชิ่อตัวชี้วัด'}`]"
hide-bottom-space
/>
</div>
<div class="col-3">
<q-input
outlined
v-model="planData.Data3"
label="ค่าเป้าหมาย"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกค่าเป้าหมาย'}`]"
hide-bottom-space
/>
</div>
<div class="col-3">
<q-input
outlined
v-model="planData.Data4"
label="หน่วยนับ"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกหน่วยนับ'}`]"
hide-bottom-space
/>
</div>
<div class="col-3">
<q-input
outlined
v-model="planData.Data5"
label="น้ำหนัก"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกน้ำหนัก'}`]"
hide-bottom-space
/>
</div>
<div class="col-12 row">
<div class="col-6">
<q-card bordered>
<q-card-actions class="bg-grey-3 row">
<div class="col-4 flex justify-center items-center">
<div>ระดบคะแนน</div>
</div>
<div class="col-8 q-px-xl">ผลสำเรจของงาน</div>
</q-card-actions>
</q-card>
<div class="row">
<div class="col-4 flex justify-center items-center">
<div>5</div>
</div>
<div class="col-8 q-pa-sm">
<q-input
outlined
v-model="planData.point5"
label="ระดับคะแนน"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกระดับคะแนน'}`]"
hide-bottom-space
/>
</div>
</div>
<div class="row">
<div class="col-4 flex justify-center items-center">
<div>4</div>
</div>
<div class="col-8 q-pa-sm">
<q-input
outlined
v-model="planData.point4"
label="ระดับคะแนน"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกระดับคะแนน'}`]"
hide-bottom-space
/>
</div>
</div>
<div class="row">
<div class="col-4 flex justify-center items-center">
<div>3</div>
</div>
<div class="col-8 q-pa-sm">
<q-input
outlined
v-model="planData.point3"
label="ระดับคะแนน"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกระดับคะแนน'}`]"
hide-bottom-space
/>
</div>
</div>
<div class="row">
<div class="col-4 flex justify-center items-center">
<div>2</div>
</div>
<div class="col-8 q-pa-sm">
<q-input
outlined
v-model="planData.point2"
label="ระดับคะแนน"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกระดับคะแนน'}`]"
hide-bottom-space
/>
</div>
</div>
<div class="row">
<div class="col-4 flex justify-center items-center">
<div>1</div>
</div>
<div class="col-8 q-pa-sm">
<q-input
outlined
v-model="planData.point1"
label="ระดับคะแนน"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกระดับคะแนน'}`]"
hide-bottom-space
/>
</div>
</div>
</div>
</div>
<div class="col-12">
<q-input
outlined
v-model="planData.Data7"
label="นิยามหรือความหมาย"
type="textarea"
bg-color="white"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกนิยามหรือความหมาย'}`]"
hide-bottom-space
/>
</div>
<div class="col-12">
<q-input
outlined
v-model="planData.Data8"
label="สูตรคำนวณ"
bg-color="white"
type="textarea"
dense
class="inputgreen"
:rules="[(val) => !!val || `${'กรุณากรอกสูตรคำนวณ'}`]"
hide-bottom-space
/>
</div>
<div class="col-6">
<q-card bordered class="col-12">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
หนวยงาน
</div>
<q-separator />
<q-card-section class="q-pa-sm">
<q-input dense outlined v-model="filterAgency" label="ค้นหา">
<template v-slot:append>
<q-icon
v-if="filterAgency !== ''"
name="clear"
class="cursor-pointer"
@click="filterAgency = ''"
/>
<q-icon v-else name="search" color="grey-5" />
</template>
</q-input>
<q-tree
dense
:nodes="nodeAgency"
node-key="orgTreeId"
label-key="labelName"
default-expand-all
:filter="filterAgency"
:no-results-label="notFound"
:no-nodes-label="noData"
v-model:expanded="expandedAgency"
>
<template v-slot:default-header="prop">
<q-item
clickable
:active="nodeId == prop.node.orgTreeId"
@click.stop="updateSelected(prop.node)"
active-class="my-list-link text-primary text-weight-medium"
class="row col-12 items-center text-dark q-py-xs q-pl-sm rounded-borders my-list"
>
<div>
<div class="text-weight-medium">
{{ prop.node.orgTreeName }}
</div>
<div class="text-weight-light text-grey-8">
{{
prop.node.orgCode == null ? null : prop.node.orgCode
}}
{{
prop.node.orgTreeShortName == null
? null
: prop.node.orgTreeShortName
}}
</div>
</div>
</q-item>
</template>
</q-tree>
</q-card-section>
</q-card>
</div>
<div class="col-6">
<q-card bordered class="col-12">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
ทธศาสตร / แผน
</div>
<q-separator />
<q-card-section class="q-pa-sm">
<q-input dense outlined v-model="filter" label="ค้นหา">
<template v-slot:append>
<q-icon
v-if="filter !== ''"
name="clear"
class="cursor-pointer"
@click="filter = ''"
/>
<q-icon v-else name="search" color="grey-5" />
</template>
</q-input>
<q-tree
dense
:nodes="nodeplan"
selected-color="primary"
node-key="id"
label-key="id"
:filter="filter"
:no-results-label="notFound"
:no-nodes-label="noData"
v-model:expanded="expandedPlan"
>
<template v-slot:default-header="prop">
<q-item
clickable
@click.stop="updateSelected(prop.node)"
:active="planData.strategyChildPlannedId == prop.node.id"
active-class="my-list-link text-primary text-weight-medium"
class="row col-12 items-center text-dark q-py-xs q-pl-sm rounded-borders my-list"
>
<div>
<div class="text-weight-medium">
{{ prop.node.name }}
</div>
</div>
</q-item>
</template>
</q-tree>
</q-card-section>
</q-card>
</div>
</div>
<q-separator color="grey-4" />
</div>
<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-form>
</template>
<style scoped></style>