hrms-mgt/src/modules/02_organizational/views/MainTree.vue

1813 lines
65 KiB
Vue

<!-- =============================== -->
<!-- หน งโครงสราง(Tree) ของ โครงสรางอตรากำล -->
<!-- =============================== -->
<template>
<div class="toptitle text-dark col-12 row items-center">งโครงสราง</div>
<div class="text-dark">
<q-card flat bordered class="col-12 q-mt-sm">
<q-layout
view="hHh Lpr lff"
container
style="height: 80vh"
class="shadow-2 rounded-borders page-relative"
>
<!--Drawer Person Detail-->
<q-drawer
v-model="isDrawer"
:width="220"
:breakpoint="400"
class="bg-grey-1"
bordered
>
<q-btn
size="13px"
class="btn-absolute btnShadow"
color="white"
dense
round
unelevated
@click="isDrawer = false"
v-if="isDrawer"
>
<q-icon name="chevron_left" size="20px" color="grey-7" />
</q-btn>
<q-scroll-area class="fit">
<div class="row col-12 text-dark q-pt-sm">
<div class="col-12 column items-center q-py-lg">
<img
v-if="
personDetail == null ||
personDetail.avatar == '' ||
personDetail.avatar ==
'https://cdn.quasar.dev/img/boy-avatar.png'
"
src="@/assets/avatar_user.jpg"
style="width: 90px; height: 90px; border-radius: 50%"
/>
<img
v-else
:src="personDetail.avatar"
style="width: 90px; height: 90px; border-radius: 50%"
/>
</div>
<div class="col-12 items-center row col-12 justify-center">
<div style="font-weight: 600" class="q-mr-xs">
{{ personDetail ? personDetail.name : "" }}
</div>
<q-btn dense flat size="10px">
<q-icon
name="mdi-open-in-new"
size="15px"
color="grey-6"
@click="goToUserRegistry()"
/>
<q-tooltip>ทะเบียนประวัติ</q-tooltip>
</q-btn>
</div>
<div class="q-pl-lg q-pt-sm q-gutter-xs textSub">
<div class="text-weight-medium q-pt-md row items-center">
<q-icon size="10px" color="grey-4" name="mdi-circle" />
<div class="q-pl-sm">ตำแหน่งเลขที่</div>
</div>
<div class="text-grey-7 q-pl-lg">
{{ personDetail ? personDetail.positionNum : "" }}
</div>
<!-- <div class="text-weight-medium q-pt-md row items-center">
<q-icon size="10px" color="grey-4" name="mdi-circle" />
<div class="q-pl-sm">ตำแหน่งในการบริหารงาน</div>
</div>
<div class="text-grey-7 q-pl-lg">
{{ personDetail ? personDetail.executivePosition : "" }}
</div> -->
<div class="text-weight-medium q-pt-md row items-center">
<q-icon size="10px" color="grey-4" name="mdi-circle" />
<div class="q-pl-sm">ประเภทตำแหน่ง</div>
</div>
<div class="text-grey-7 q-pl-lg">
{{ personDetail ? personDetail.positionType : "" }}
</div>
<div class="text-weight-medium q-pt-md row items-center">
<q-icon size="10px" color="grey-4" name="mdi-circle" />
<div class="q-pl-sm">ระดับตำแหน่ง</div>
</div>
<div class="text-grey-7 q-pl-lg">
{{ personDetail ? personDetail.positionLevel : "" }}
</div>
</div>
</div>
</q-scroll-area>
</q-drawer>
<!--Edit Button Set and Search Tree input and Show Free positionNum-->
<q-page-container class="col-12 row">
<q-page padding style="padding-top: 70px">
<!-- Button Set -->
<q-page-sticky
expand
position="top"
class="bg-white pageSK q-pt-sm"
>
<div
class="col-12 q-px-md row items-center q-py-sm q-col-gutter-xs"
>
<div class="row">
<buttonsSet
v-model:editvisible="isShowEditTree"
:deleteDraft="deleteDraft"
:publishDraft="publishDraft"
:refreshData="resetTree"
:publicData="version === 'published'"
/><q-btn
color="info"
flat
dense
round
size="14px"
icon="mdi-history"
@click="clickHistory"
><q-tooltip>ประวัติการเผยแพร่</q-tooltip>
</q-btn>
</div>
<q-space />
<q-select
dense
outlined
v-model="selectedFile"
:options="fileList"
class="col-xs-12 col-sm-4 col-md-3"
map-options
emit-value
v-if="!isShowEditTree"
/>
<q-input
outlined
dense
style="max-width: 200px"
ref="treeFilterRef"
v-model="treeFilter"
placeholder="ค้นหา"
debounce="300"
>
<template v-slot:append>
<q-icon v-if="treeFilter == ''" name="search" />
<q-icon
v-if="treeFilter !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template>
</q-input>
</div>
</q-page-sticky>
<!-- Tree View-->
<div class="q-gutter-sm">
<q-tree
v-show="!isShowEditTree"
no-transition
ref="qtreeView"
:nodes="dataTree"
:no-results-label="treeSearchNotFound"
:no-nodes-label="noTreeData"
node-key="keyId"
:filter="treeFilter"
:filter-method="treeFilterMethod"
v-model:expanded="expandedNodeView"
>
<!--organization บรรทัดแสดงชื่อหน่วยงาน -->
<template v-slot:header-organization="prop">
<div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
<!--แสดงชื่อแผนก พิมพ์ตัวหนา คลิกแล้วกาง/หุบ Tree-->
<div>
<div class="text-weight-medium">
{{ prop.node.organizationName }}
</div>
<div class="text-weight-light">
{{
prop.node.organizationParentId == null
? null
: prop.node.governmentCode
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.agency
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.government
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.department
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.pile
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.organizationShortName
}}
</div>
</div>
<!--แสดง Total Count PositionNum-->
<q-badge
rounded
color="grey-2"
text-color="dark"
:label="prop.node.totalPositionCount"
/>
<q-badge
v-if="prop.node.totalPositionVacant > 0"
rounded
color="red"
outline
:label="prop.node.totalPositionVacant"
/>
</div>
</template>
<!--person บรรทัดแถวแสดงชื่อพนักงานอย่างเดียว-->
<template v-slot:header-person="prop">
<div
class="row items-center text-dark col-12 q-py-xs q-pl-sm rounded-borders pointer"
style="width: 100%"
>
<img
v-if="
prop.node.avatar == '' ||
prop.node.avatar ==
'https://cdn.quasar.dev/img/boy-avatar.png'
"
src="@/assets/avatar_user.jpg"
class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%"
/>
<img
v-else
:src="prop.node.avatar"
class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%"
/>
<div class="row" @click="seeUserDetail(prop.node)">
<!--=====ตำแหน่งว่าง สีแดง=====-->
<div
v-if="
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` ||
prop.node.name == null
"
class="q-px-sm text-weight-medium text-red"
>
ว่าง
</div>
<!--=====หัวหน้า สีเขียว=====-->
<div v-else-if="prop.node.positionLeaderFlag">
<div class="q-px-sm text-weight-medium text-primary">
{{ prop.node.name }}
</div>
</div>
<!--=====ลูกน้อง สีปกติ=====-->
<div v-else>
<div class="q-px-sm text-weight-medium">
{{ prop.node.name }}
</div>
</div>
<!--ต่อท้ายชื่อคน แสดงสีปกติ-->
<div class="q-pr-sm">
{{ prop.node.positionName }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.positionType != null &&
prop.node.positionType != ''
"
>
ประเภท{{ `${prop.node.positionType}` }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.positionLevel != null &&
prop.node.positionLevel != ''
"
>
ระดับ{{ `${prop.node.positionLevel}` }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.executivePosition != null &&
prop.node.executivePosition != ''
"
>
{{ `(${prop.node.executivePosition})` }}
</div>
<div class="q-pr-sm">
{{ prop.node.positionNum }}
</div>
</div>
<q-icon
v-if="prop.node.positionLeaderFlag"
class="q-mr-sm"
size="15px"
color="primary"
name="mdi-bookmark"
/>
<!-- <div
class="text-white"
style="font-size: 1px; display: none"
>
{{ prop.node.positionLevel }}
</div> -->
</div>
</template>
</q-tree>
</div>
<!--Tree Edit-->
<div class="q-gutter-sm">
<!-- must use v-if to be able to use lazyLoad for second time-->
<q-tree
v-if="isShowEditTree"
no-transition
ref="qtreeEdit"
:nodes="dataTreeDraft"
:no-results-label="treeSearchNotFound"
:no-nodes-label="noTreeData"
node-key="keyId"
:filter="treeFilter"
:filter-method="treeFilterMethod"
@lazy-load="onLazyLoad"
v-model:expanded="expandedNodeEdit"
dense
>
<!--organization บรรทัดแสดงชื่อหน่วยงาน & ปุ่ม + -->
<template v-slot:header-organization="prop">
<div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
<!--แสดงชื่อแผนก พิมพ์ตัวหนา คลิกแล้วกาง/หุบ Tree-->
<div>
<div class="text-weight-medium">
{{ prop.node.organizationName }}
</div>
<div class="text-weight-light">
{{
prop.node.organizationParentId == null
? null
: prop.node.governmentCode
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.agency
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.government
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.department
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.pile
}}
{{
prop.node.organizationParentId == null
? null
: prop.node.organizationShortName
}}
</div>
</div>
<!--แสดง Total Count PositionNum-->
<q-badge
rounded
color="grey-2"
text-color="dark"
:label="prop.node.totalPositionCount"
/>
<q-badge
v-if="prop.node.totalPositionVacant > 0"
rounded
color="red"
outline
:label="prop.node.totalPositionVacant"
/>
<q-btn
flat
round
color="green"
@click.stop="
(popupAddOrganization = true),
(modalHeaderName = prop.node.organizationName),
(rowClickTree = prop.node),
(modalHeaderPosition =
prop.node.keyId.search('-') > 0 ? true : false)
"
size="10px"
icon="mdi-plus"
>
<q-tooltip>เพิ่มโครงสร้าง</q-tooltip>
</q-btn>
<!--
v-if="
prop.node.totalPositionCount ==
prop.node.totalPositionVacant
"
-->
<q-btn
v-if="prop.node.organizationId != orgRootIdDraft"
flat
round
color="edit"
@click.stop="
(popupEditSelectedOrganization = true),
(modalHeaderName = prop.node.organizationName),
(rowClickTree = prop.node),
(modalHeaderPosition =
prop.node.keyId.search('-') > 0 ? true : false)
"
size="10px"
icon="mdi-pencil"
>
<q-tooltip>แก้ไขหน่วยงาน</q-tooltip>
</q-btn>
<q-btn
v-if="
prop.node.totalPositionCount ==
prop.node.totalPositionVacant &&
prop.node.organizationId != orgRootIdDraft
"
flat
round
color="red"
size="10px"
class="q-mr-sm"
icon="mdi-trash-can-outline"
@click.stop="deleteOrganization(prop.node)"
>
<q-tooltip>ลบหน่วยงาน</q-tooltip>
</q-btn>
<q-space />
</div>
</template>
<!--person บรรทัดแถวแสดงชื่อพนักงานอย่างเดียว-->
<template v-slot:header-person="prop">
<div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
<div
rounded
:style="
!prop.node.isActive ? 'filter: grayscale(60%);' : ''
"
>
<img
v-if="
prop.node.avatar == '' ||
prop.node.avatar ==
'https://cdn.quasar.dev/img/boy-avatar.png'
"
src="@/assets/avatar_user.jpg"
class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%"
/>
<img
v-else
:src="prop.node.avatar"
class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%"
/>
</div>
<div
rounded
:class="
!prop.node.isActive ? 'text-grey-6' : 'text-black'
"
>
<!--=====ตำแหน่งว่าง สีแดง=====-->
<div class="row">
<div
v-if="
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` ||
prop.node.name == null
"
class="q-px-sm text-weight-medium"
:class="
!prop.node.isActive ? 'text-grey-6' : 'text-red'
"
>
ว่าง
</div>
<!--=====หัวหน้า สีเขียว=====-->
<div v-else-if="prop.node.positionLeaderFlag">
<div class="q-px-sm text-weight-medium text-primary">
{{ prop.node.name }}
</div>
</div>
<!--=====ลูกน้อง สีปกติ=====-->
<div v-else>
<div class="q-px-sm text-weight-medium">
{{ prop.node.name }}
</div>
</div>
<!--ต่อท้ายชื่อคน แสดงสีปกติ-->
<div class="q-pr-sm">
{{ prop.node.positionName }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.positionType != null &&
prop.node.positionType != ''
"
>
ประเภท{{ prop.node.positionType }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.positionLevel != null &&
prop.node.positionLevel != ''
"
>
ระดับ{{ prop.node.positionLevel }}
</div>
<div
class="q-pr-sm"
v-if="
prop.node.executivePosition != null &&
prop.node.executivePosition != ''
"
>
{{ `(${prop.node.executivePosition})` }}
</div>
<div class="q-pr-sm">
{{ prop.node.positionNum }}
</div>
</div>
<div class="q-pl-sm text-weight-light">
{{ prop.node.positionSideName }}
<!-- {{ prop.node.executivePosition }} -->
{{ prop.node.executivePositionSide }}
</div>
</div>
<q-icon
v-if="prop.node.positionLeaderFlag"
class="q-mr-sm"
size="15px"
color="primary"
name="mdi-bookmark"
></q-icon
><q-btn
v-if="
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` ||
prop.node.name == null
"
flat
round
color="green"
@click.stop="
(popupEditSelectedPosition = true),
(modalHeaderName = prop.node.positionName),
(rowClickTree = prop.node),
(modalHeaderPosition =
prop.node.keyId.search('-') > 0 ? true : false)
"
size="10px"
icon="mdi-pencil-outline"
>
<q-tooltip>แก้ไขตำแหน่ง</q-tooltip>
</q-btn>
<q-btn
v-if="
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` ||
prop.node.name == null
"
flat
round
color="red"
size="10px"
class="q-mr-sm"
icon="mdi-trash-can-outline"
@click.stop="deletePosition(prop.node)"
>
<q-tooltip>ลบตำแหน่ง</q-tooltip>
</q-btn>
<q-space />
<!-- <div
class="text-white"
style="font-size: 1px; display: none"
>
{{ prop.node.positionLevel }}
</div> -->
</div>
</template>
</q-tree>
</div>
</q-page>
</q-page-container>
<!-- popup Add Organizations & Positions -->
<q-dialog v-model="popupAddOrganization" persistent>
<q-card class="text-dark" style="min-width: 950px">
<q-card-section class="row items-center q-py-sm">
<div class="text-bold">เพิ่มโครงสร้างอัตรากำลังภายใต้</div>
<strong class="text-primary q-pl-sm">{{
modalHeaderName
}}</strong>
<q-space />
<q-btn
icon="close"
unelevated
round
dense
style="color: #ff8080; background-color: #ffdede"
size="12px"
v-close-popup
/>
</q-card-section>
<q-separator />
<q-card-section
style="min-height: 60vh; max-height: 70vh"
class="scroll"
>
<organizationComponent
v-model:organizprops="organizationData"
v-model:formprops="organizationForm"
/>
<br />
<positionsComponent
v-model:positions="positionData"
v-model:formprops="positionForm"
:is-add-new="true"
v-if="modalHeaderPosition"
/>
</q-card-section>
<q-separator />
<q-card-actions align="right" class="text-primary q-py-sm">
<!-- Save for Add Organizations & Positions -->
<q-btn
flat
round
dense
:color="'public'"
@click="addStructure(rowClickTree)"
icon="mdi-content-save-outline"
>
<q-tooltip>บันทึก</q-tooltip>
</q-btn>
</q-card-actions>
</q-card>
</q-dialog>
<!-- popup Edit Selected Position -->
<q-dialog v-model="popupEditSelectedPosition" persistent>
<q-card class="text-dark" style="min-width: 70vw">
<q-card-section class="row items-center q-py-sm">
<div class="text-bold">แก้ไขตำแหน่ง</div>
<strong class="text-primary q-pl-sm">{{
modalHeaderName
}}</strong>
<q-space />
<q-btn
icon="close"
unelevated
round
dense
style="color: #ff8080; background-color: #ffdede"
size="12px"
v-close-popup
/>
</q-card-section>
<q-separator />
<q-card-section>
<positionsComponent
v-model:positions="positionData"
v-model:formprops="positionForm"
:is-add-new="false"
:editObj="rowClickTree"
/>
</q-card-section>
<q-separator />
<q-card-actions align="right" class="text-primary q-py-sm">
<!-- save Edit Selected Position -->
<q-btn
flat
dense
round
:color="'public'"
@click="editPositionStructure(rowClickTree)"
icon="mdi-content-save-outline"
>
<q-tooltip>บันทึก</q-tooltip>
</q-btn>
</q-card-actions>
</q-card>
</q-dialog>
<!-- popup Edit Selected Organization -->
<q-dialog v-model="popupEditSelectedOrganization" persistent>
<q-card class="text-dark" style="min-width: 70vw">
<q-card-section class="row items-center q-py-sm">
<div class="text-bold">แก้ไขหน่วยงาน</div>
<strong class="text-primary q-pl-sm">{{
modalHeaderName
}}</strong>
<q-space />
<q-btn
icon="close"
unelevated
round
dense
style="color: #ff8080; background-color: #ffdede"
size="12px"
v-close-popup
/>
</q-card-section>
<q-separator />
<q-card-section>
<organizationEditComponent
v-model:organizprops="organizationDataEdit"
v-model:formprops="organizationForm"
:org="rowClickTree"
/>
</q-card-section>
<q-separator />
<q-card-actions align="right" class="text-primary q-py-sm">
<!-- save Edit Selected Organization -->
<q-btn
flat
dense
round
:color="'public'"
@click="editOrgStructure(rowClickTree)"
icon="mdi-content-save-outline"
>
<q-tooltip>บันทึก</q-tooltip>
</q-btn>
</q-card-actions>
</q-card>
</q-dialog>
</q-layout>
</q-card>
</div>
<HistoryTable
:rows="rowsHistory"
:columns="columnsHistory"
:filter="filterHistory"
:visible-columns="visibleColumnsHistory"
:boss="true"
v-model:modal="modalHistory"
v-model:inputfilter="filterHistory"
v-model:inputvisible="visibleColumnsHistory"
v-model:tittle="tittleHistory"
>
<template #columns="props">
<q-tr :props="props">
<q-td auto-width>
<q-icon
class="q-mr-sm"
size="15px"
color="primary"
name="mdi-bookmark"
v-if="props.row.isDirector"
></q-icon>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div v-if="col.name == 'isActive'" class="">
<q-icon
v-if="col.value == false"
name="mdi-close"
color="red"
class="text-h5"
/>
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
</div>
<div v-else class="">
{{ col.value }}
</div>
</q-td>
</q-tr>
</template>
</HistoryTable>
</template>
<script setup lang="ts">
// import tree_data from "@/assets/tree.json";
import { stringLiteral, typeParameterDeclaration } from "@babel/types";
import { ref, defineAsyncComponent, watch, onMounted } from "vue";
import { useQuasar, QForm } from "quasar";
import { useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import type { OrganizaOption } from "../interface/index/Main";
// import manageApiErrorMsg from "@/global/user_response_msg";
import HistoryTable from "@/components/TableHistory.vue";
import type { QTableProps } from "quasar";
import type {
RequestItemsObject,
RequestItemsPublishHistoryObject,
Columns,
} from "@/modules/02_organizational/interface/request/Mapping";
const positionsComponent = defineAsyncComponent(
() =>
import("@/modules/02_organizational/components/Tree/MappingPositions.vue")
); //ชุด Dropdown ตำแหน่ง
const organizationComponent = defineAsyncComponent(
() =>
import("@/modules/02_organizational/components/Tree/OrganizationDialog.vue")
); //ชุด Dropdown หน่วยงาน for Add
const organizationEditComponent = defineAsyncComponent(
() =>
import(
"@/modules/02_organizational/components/Tree/OrganizationDialogAddEdit.vue"
)
); //ชุด Dropdown หน่วยงาน for Edit ครั้งละ 1 หน่วยงาน
const buttonsSet = defineAsyncComponent(
() => import("@/modules/02_organizational/components/Tree/TreeButtonsSet.vue")
); //ชุด ปุ่มกด copy from TableView but delete Table
// import CustomComponent from "@/components/CustomDialog.vue";
const rowsHistory = ref<any[]>([]); //select data history
const rawHistory = ref<any[]>([]); //raw data history
const tittleHistory = ref<string>("ประวัติแก้ไขผังโครงสร้าง"); //
const filterHistory = ref<string>(""); //search data table history
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
//Global Variable
const mixin = useCounterMixin();
const { success, messageError, dialogMessage, showLoader, hideLoader } = mixin;
//Notification Component Variable
const $q = useQuasar(); // show dialog
//Drawer Person Detail Variable
const router = useRouter();
const isDrawer = ref<boolean>(false);
const isChevronR = ref<boolean>(false); //don't show Drawer btn when first load page
const personDetail = ref<any>();
//Pop-Up Add/Edit Organization Variable
const popupAddOrganization = ref<boolean>(false); //แสดง pop-up เพิ่ม mapping โครงสร้าง
const popupEditSelectedOrganization = ref<boolean>(false); //แสดง pop-up Edit หน่วยงานที่เลือก
const popupEditSelectedPosition = ref<boolean>(false); //แสดง pop-up Edit ตำแหน่งที่เลือก
const modalHeaderName = ref<string>("กรุงเทพมหานคร/สำนักงาน ก.ก."); //show name of click node on modal
const modalHeaderPosition = ref<boolean>(true);
//ButtonSet Variable
const version = ref<string>("published"); // คำอื่นจะเปิดปุ่มให้กดได้ :publicData="version === 'published'" (True = Disable Buttons) -->
const isShowEditTree = ref<boolean>(false); //ปุ่ม edit บน buttonSet //true=draft load draft first
//Tree Variable
const expandedNodeView = ref<Array<string>>([]);
const expandedNodeEdit = ref<Array<string>>([]);
const treeFilter = ref<string>("");
const treeFilterRef = ref<any>(null);
const treeSearchNotFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
const noTreeData = ref<string>("ไม่พบข้อมูลผังโครงสร้าง");
const organizationForm = ref<QForm | null>(null);
const positionForm = ref<QForm | null>(null);
const qtreeView = ref<any>(); //q-tree ref for View
const qtreeEdit = ref<any>(); //q-tree ref for Edit
const positionData = ref<Array<any>>([]); //๋Array เก็บ positionSet from positionsComponent
const organizationData = ref<OrganizaOption[]>([]);
const organizationDataEdit = ref<OrganizaOption>();
const orgRootIdDraft = ref<string>(""); // Draft Root Node for not show edit&delete button
const rowClickTree = ref<Array<Object>>([]); //keep click node and all of it's children
const dataTree = ref<Array<any>>([]);
// const dataTree = ref<Array<any>>(jsonDataTree);
const dataTreeDraft = ref<Array<any>>([]);
//deledte Organization & Position Variable function
const delStructureId = ref<string>("");
const delStructureKey = ref<string>("");
// first load page
const rootNodeKey = ref<string>("");
const fileList = ref<any[]>([]);
const selectedFile = ref<string>("");
const visibleColumnsHistory = ref<String[]>(["detail", "editUser", "editDate"]);
const columnsHistory = ref<QTableProps["columns"]>([
{
name: "detail",
align: "left",
label: "รายละเอียด",
sortable: true,
field: "detail",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, {
numeric: true,
sensitivity: "base",
}),
},
{
name: "editUser",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "editUser",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, {
numeric: true,
sensitivity: "base",
}),
},
{
name: "editDate",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "editDate",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, {
numeric: true,
sensitivity: "base",
}),
},
]);
watch(isShowEditTree, (count, prevCount) => {
if (isShowEditTree.value) {
isDrawer.value = false;
}
}); // close drawer when enter edit mode
watch(selectedFile, async (value, oldValue) => {
await loadJsonTree(value);
});
onMounted(async () => {
await fetchTreeRoot(true); //fetch Root Edit Tree level 1
expandedNodeView.value = [`1`];
await loadPublishScreen();
await isTreeHasDraft();
});
const loadTreeData = async () => {
//for test load file on server
await http
.get(
// "https://s3cluster.frappet.com/bma-public-test/organization/strueture/tree.json"
// "https://s3cluster.frappet.com/bma-public-test/organization/strueture/1-2-สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร.json"
// `https://s3cluster.frappet.com/bma-public-test/organization/strueture/${node.organizationId}-${node.organizationName}.json`
"https://s3cluster.frappet.com/bma-public-test/organization/strueture/61a11705-8346-4336-8289-49f72ed9463f-%E0%B8%AA%E0%B8%B3%E0%B8%99%E0%B8%B1%E0%B8%81%E0%B8%87%E0%B8%B2%E0%B8%99%E0%B8%84%E0%B8%93%E0%B8%B0%E0%B8%81%E0%B8%A3%E0%B8%A3%E0%B8%A1%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%82%E0%B9%89%E0%B8%B2%E0%B8%A3%E0%B8%B2%E0%B8%8A%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%81%E0%B8%A3%E0%B8%B8%E0%B8%87%E0%B9%80%E0%B8%97%E0%B8%9E%E0%B8%A1%E0%B8%AB%E0%B8%B2%E0%B8%99%E0%B8%84%E0%B8%A3.json"
)
.then((res) => {
dataTree.value = res.data.result;
})
.catch((e) => {
manageApiErrorMsg(e);
});
};
const loadViewTree = async () => {
await fetchTreeRoot(false); //fetch root view tree level 1
dataTree.value[0].lazy = false; //must set lazy to false
await fetchChildrenByParentId(dataTree.value[0]); // fetch children view tree level 2
dataTree.value[0].children.forEach((element: any) => {
//fill all children of all level 2 nodes
loadFileServer(element);
});
};
const loadPublishScreen = async () => {
await fetchPublishFile();
expandedNodeView.value = [`1`];
setTimeout(async () => {
await fetchTreeRoot(false); //fetch root view tree level 1
dataTree.value[0].lazy = false; //must set lazy to false
await loadJsonTree(selectedFile.value);
}, 600);
};
const loadJsonTree = async (fileName: string) => {
await http
.get(`${config.s3ClusterUrl}${fileName}`)
.then((res) => {
dataTree.value[0].lazy = false; //must set lazy to false
dataTree.value[0].children = res.data;
})
.catch((e) => {
manageApiErrorMsg(e);
})
.finally(() => {
// hideLoader();
});
};
const loadFileServer = async (node: any) => {
// test data = "https://s3cluster.frappet.com/bma-public-test/organization/strueture/tree.json"
// request = `https://s3cluster.frappet.com/bma-public-test/organization/strueture/${node.organizationId}-${node.organizationName}.json`;
node.lazy = false; // must set lazy to false
await http
.get(
`${config.s3ClusterUrl}${node.organizationId}-${node.organizationName}.json`
)
.then((res) => {
node.children = res.data;
})
.catch((e) => {
manageApiErrorMsg(e);
})
.finally(() => {
// hideLoader();
});
};
const isTreeHasDraft = async () => {
// showLoader();
let orgHasDraft = false;
let orgPoHasDraft = false;
await http
.get(config.API.isOrgPohasDraft)
.then((res) => {
orgPoHasDraft = res.data.result;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
// hideLoader();
});
await http
.get(config.API.isOrghasDraft)
.then((res) => {
orgHasDraft = res.data.result;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
// hideLoader();
});
if (orgHasDraft || orgPoHasDraft) {
version.value = "";
} else {
version.value = "published";
}
};
/**โหลด Tree Root Node
* @param isDraft แสดงข้อมูลดราฟหรือ Production
*/
const fetchTreeRoot = async (isDraft: boolean) => {
showLoader();
console.log("Call API14 GetTreeRoot");
isShowEditTree.value = isDraft; // to show same tree that we fetch
let request = "";
if (isDraft) {
request = config.API.getDraftTreeRoot;
} else {
request = config.API.getTreeRoot;
}
await http
.get(request)
.then((res) => {
if (isDraft) {
dataTreeDraft.value = res.data.result;
orgRootIdDraft.value = res.data.result[0].organizationId;
} else {
dataTree.value = res.data.result;
rootNodeKey.value = res.data.result[0].organizationId;
}
})
.catch((e) => {
// console.log(e);
// console.log(e.response);
manageApiErrorMsg(e);
// messageError($q, e);
})
.finally(() => {
hideLoader();
if (isDraft) {
// ถ้าไม่ต้องการให้แตก node root on first load ก็ไม่ต้องใส่
// ต้องอยู่ตรงนี้ ถ้าอยู่ตรง .then จะ error คาดว่ามันทำงานก่อนที่ tree จะ render เสร็จ แต่ก็อาจจะไม่ใช่
qtreeEdit.value.setExpanded(dataTreeDraft.value[0].keyId, true);
expandedNodeEdit.value = [dataTreeDraft.value[0].keyId];
} else {
qtreeView.value.setExpanded(dataTree.value[0].keyId, true);
}
});
};
/**โหลดลูก Tree
* @param node Parent Node
*/
const fetchChildrenByParentId = async (node: any) => {
// console.log(isDraft);
console.log("Call API4");
showLoader();
let request = "";
if (isShowEditTree.value) {
request = config.API.getDraftTreeNode(node.organizationId, node.keyId);
} else {
request = config.API.getTreeNode(node.organizationId, node.keyId);
}
await http
.get(request)
.then((res) => {
console.log(res.data.result);
node.children = res.data.result;
})
.catch((e) => {
// console.log(e);
// console.log(e.response);
manageApiErrorMsg(e);
})
.finally(() => {
hideLoader();
});
};
const fetchPublishFile = async () => {
showLoader();
await http
.get(config.API.getPublishFileHistory)
.then((res) => {
let data = res.data.result;
fileList.value = [];
data.map((e: any) => {
fileList.value.push({
value: e.fileName,
label: e.description,
});
});
selectedFile.value = fileList.value[0].value;
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
});
};
/**
* ฟังก์ชันสำหรับโหลด data tree ทีละชุด
* use by set @lazy-load="onLazyLoad" on q-tree
* @param node Auto send by Quasar Tree no need to send anything
*/
const onLazyLoad = (node: any) => {
setTimeout(async () => {
/**
* เรียก API4 มาแสดงผล ทีละ shot
*/
console.log("Call LazyLoad");
await fetchChildrenByParentId(node.node);
/** showLoader();
let request = "";
if (isShowEditTree.value) {
request = config.API.getDraftTreeNode(
node.node.organizationId,
node.node.keyId
);
} else {
//comment Jack's code
// if (node.node.organizationId == rootNodeKey.value) {
request = config.API.getTreeNode(
node.node.organizationId,
node.node.keyId
);
// } else {
// request = `https://s3cluster.frappet.com/bma-public-test/organization/strueture/${node.node.organizationId}-${node.node.organizationName}.json`;
// }
}
await http
.get(request)
.then((res) => {
// console.log(res.data.result);
//start Jack's code
// if (node.node.organizationId == rootNodeKey.value)
// node.node.children = res.data.result;
// else node.node.children = res.data;
//end Jack's code
node.node.children = res.data.result;
})
.catch((e) => {
// console.log(e);
// console.log(e.response);
manageApiErrorMsg(e);
// messageError($q, e);
})
.finally(() => {
hideLoader();
});*/
node.done(node.node.children); //return ค่าให้ q-tree generate children
}, 10);
};
/**====== Drawer Functions
* ========================
*/
const goToUserRegistry = () => {
router.push(`/registry/${personDetail.value.profileId}`);
};
/**
* ฟังก์ชันที่ดูข้อมูลผู้ใช้งานจาก tree
* @param node user ใน tree ที่จะดูข้อมูล (prop.node)
*/
const seeUserDetail = (node: any) => {
if (node.name != null) {
isChevronR.value = true;
isDrawer.value = true;
// personDetail.value = JSON.parse(JSON.stringify(node));
personDetail.value = node;
}
};
/**====== Pop-up Add/Edit/Delete Organization Functions
* ========================
*/
/**ลบหน่วยงานที่ตำแหน่งทั้งหมดที่มีว่างหมด
* Call API Delete when confirm
* @param node node that you want to delete (prop.node)
*/
const deleteOrganization = (node: any) => {
delStructureId.value = node.organizationId;
delStructureKey.value = node.keyId;
dialogMessage(
$q,
"ยืนยันลบหน่วยงาน",
"หากต้องการลบกดตกลง",
"mdi-help-circle-outline",
"ตกลง",
"red",
apiDeleteOrg,
undefined
);
};
const apiDeleteOrg = () => {
// const deleteOrganization = (node: any) => {
isShowEditTree.value = false;
// console.log("isShowEditTree", isShowEditTree.value);
setTimeout(async () => {
//delay for lazyLoad to be able to tricker again
showLoader();
isShowEditTree.value = true;
await http
.delete(config.API.delTreeOrgDraft(delStructureId.value))
.then((res) => {
success($q, "ลบข้อมูลสำเร็จ");
// console.log("delStructureKey", delStructureKey.value);
const nodeSplit = delStructureKey.value.split("-");
const nodeDelete = nodeSplit.splice(0, nodeSplit.length - 1);
const nodeJoin = nodeDelete.join("-");
// console.log("nodeJoin", nodeJoin);
qtreeEdit.value.setExpanded(nodeJoin, true);
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
await isTreeHasDraft();
});
}, 20);
};
/**ลบตำแหน่งที่ว่างออกจาก DB
* Call API Delete when confirm
* @param node node that you want to delete (prop.node)
*/
const deletePosition = (node: any) => {
delStructureId.value = node.organizationPositionId;
delStructureKey.value = node.keyId;
dialogMessage(
$q,
"ยืนยันลบตำแหน่ง",
"หากต้องการลบกดตกลง",
"mdi-help-circle-outline",
"ตกลง",
"red",
apiDeletePosition,
undefined
);
};
const apiDeletePosition = () => {
// const deletePosition = (node: any) => {
isShowEditTree.value = false;
setTimeout(async () => {
//delay for lazyLoad to be able to tricker again
showLoader();
isShowEditTree.value = true;
await http
.delete(config.API.delTreePositionDraft(delStructureId.value))
.then((res) => {
success($q, "ลบข้อมูลสำเร็จ");
const nodeSplit = delStructureKey.value.split("-");
const nodeDelete = nodeSplit.splice(0, nodeSplit.length - 1);
const nodeJoin = nodeDelete.join("-");
qtreeEdit.value.setExpanded(nodeJoin, true);
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
await isTreeHasDraft();
});
}, 20);
};
/**======ButtonSet Function
*==========================
*/
/**Delete Draft
* ฟังก์ชัน clear data แบบร่าง
*/
const deleteDraft = async () => {
showLoader();
await http
.put(config.API.delTreeOrgPoDraft)
.then((res) => {
success($q, "ลบข้อมูลร่างสำเร็จ");
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
router.go(0);
await isTreeHasDraft();
});
};
/**Publish Draft
* ฟังก์ชันเผยแพร่แบบร่าง
*/
const publishDraft = async () => {
showLoader();
await http
.put(config.API.publishOrgPoDraft)
.then((res) => {
success($q, "เผยแพร่ข้อมูลสำเร็จ");
//publish สำเร็จแล้ว ให้เช็คว่าถ้า BE generate file data เสร็จแล้วให้มีการเตือนให้ user reload viewTree ใหม่
//estimate time for be to regenerate new viewTree file is 30sec
//ยังไม่แน่ใจว่า BE จะ return success กลับมาเมื่อทำ publish สำเร็จ หรือเมื่อ generate new viewTree file เสร็จ
//ยูสเซอร์กด ตกลง ให้ Load viewTree ใหม่อีกครั้ง
dialogMessage(
$q,
"เผยแพร่ข้อมูลสำเร็จแล้ว",
"ต้องการโหลดข้อมูลใหม่หรือไม่",
"mdi-help-circle-outline",
"ตกลง",
"public",
loadViewTree,
undefined
);
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
await isTreeHasDraft();
});
};
/**Refresh Data
* clear Loacal Storage
* reload root tree
* reload สำนัก
* ไม่ใช้แล้ว ยังไม่ลบเพราะไม่รู้เป้จะอยากได้อีกไหม
*/
const resetTree = async () => {
dialogMessage(
$q,
"รีเฟรชหน้า",
"ต้องการรีเฟรชผังโครงสร้างใหม่หรือไม่",
"mdi-help-circle-outline",
"ตกลง",
"public",
loadPublishScreen,
undefined
);
}; //ไม่ใช้แล้ว ยังไม่ลบเพราะไม่รู้เป้จะอยากได้อีกไหม
const clearLocalStorage = async () => {
localStorage.removeItem("dataTree");
}; //ไม่ใช้แล้ว ยังไม่ลบเพราะไม่รู้เป้จะอยากได้อีกไหม
/**====== Tree Functions
* ========================
*/
const resetFilter = () => {
// reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
treeFilter.value = ""; // v-model="treeFilter"
treeFilterRef.value.focus(); // ref="treeFilterRef"
}; //reset Tree Filter
/**Search Tree Function
* :filter="treeFilter" - input box v-model name
* :filter-method="treeFilterMethod"
* @param node tree node Auto send by quasar tree
* @param filter searching word Auto send by quasar tree
*/
const treeFilterMethod = (node: any, filter: string) => {
const filt = filter;
let hasMatch =
(node.organizationName && node.organizationName.indexOf(filt) > -1) ||
(node.positionNum && node.positionNum.indexOf(filt) > -1) ||
(node.name && node.name.indexOf(filt) > -1) ||
(node.positionName && node.positionName.indexOf(filt) > -1) ||
(node.governmentCode &&
node.governmentCode.toString().indexOf(filt) > -1) ||
(node.agency && node.agency.indexOf(filt) > -1) ||
(node.government && node.government.indexOf(filt) > -1) ||
(node.department && node.department.indexOf(filt) > -1) ||
(node.pile && node.pile.indexOf(filt) > -1) ||
(node.organizationShortName &&
node.organizationShortName.indexOf(filt) > -1) ||
(node.positionSideName && node.positionSideName.indexOf(filt) > -1) ||
(node.executivePosition && node.executivePosition.indexOf(filt) > -1) ||
(node.executivePositionSide &&
node.executivePositionSide.indexOf(filt) > -1) ||
(node.positionLevel && node.positionLevel.indexOf(filt) > -1);
//hasMatch จะได้เป็น keyId ของ node ที่หาเจอโดย q-tree จะวนเรียก treeFilterMethod ทีละ node
//ถ้า 100 nodes ก็วนฟังชั่นนี้ 100 รอบ
//ยังไม่ใช้ เพราะเรียก api มาทีละ level user จะค่อยๆ แตก tree ออกมาอยู่แล้ว
// if (hasMatch) {
// // if the current node matches the filter, expand all nodes in the tree
// expandedNode.value.push(node.keyId);
// //expandAllNodes([node]);
// }
return hasMatch;
};
/**Add โครงสร้าง Org & Position
* API1
* @param node node that you want to add children data
*/
const addStructure = async (node: any) => {
isShowEditTree.value = false; //ซ่อน editTree เพื่อให้สามารถเรียก lazyLoad ได้อีกครั้งเมื่อกลับมาแสดง
// console.log(node);
console.log("organizationData.value", organizationData.value);
// console.log("organizationForm.value", organizationForm.value);
console.log("positionData.value", positionData.value);
let organizCheck: Boolean = false;
let positionCheck: Boolean = false;
await organizationForm.value
?.validate()
.then((e: Boolean) => (organizCheck = e));
await positionForm.value
?.validate()
.then((e: Boolean) => (positionCheck = e));
// if (positionData.value.length <= 0 && organizationData.value.length <= 0) {
// popupAddOrganization.value = false;
// } // no data to add close pop-up no message show when click save
if (
organizCheck == true &&
(positionCheck == true || modalHeaderPosition.value == false) &&
(positionData.value.length > 0 || organizationData.value.length > 0)
) {
let reqOrgAr: Array<any> = JSON.parse(
JSON.stringify(organizationData.value)
);
reqOrgAr.forEach((a: any) => {
delete a["organizationShortName"];
delete a["organizationShortCode"];
a.organizationId = node.organizationId; //parentId ของ node ที่จะสร้าง
});
// console.log(node.organizationId);
console.log("Call API1");
showLoader();
isShowEditTree.value = true; //ต้องกลับมาแสดง editTree อีกครั้ง & trigger lazyLoad โดย setExpanded
await http
.post(config.API.addTreeDraft, {
organizationId: node.organizationId, // GUID ของหน่วยงานต้นสังกัดที่ต้องการสร้างข้อมูล, // ParentId ของ Org ที่จะเพิ่มใหม่
organizations: reqOrgAr,
positions: positionData.value, // รอต่อ api dropdown ตำแหน่งก่อน
})
.then(async (res) => {
success($q, "บันทึกข้อมูลร่างสำเร็จ");
//reload it's own node to see new added nodes
qtreeEdit.value.setExpanded(node.keyId, true);
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
popupAddOrganization.value = false;
await isTreeHasDraft();
});
} else {
console.log("validation fail"); // or no data to add");
}
isShowEditTree.value = true;
};
/**Edit โครงสร้างหน่วยงาน
* API13
* @param node node that you want to edit data
*/
const editOrgStructure = async (node: any) => {
isShowEditTree.value = false; //start prepare for tricker LazyLoad
// console.log(node);
// console.log("organizationData.value", organizationData.value);
let organizCheck: Boolean = false;
await organizationForm.value
?.validate()
.then((e: Boolean) => (organizCheck = e));
// if (organizationData.value.length <= 0) {
// popupAddOrganization.value = false;
// } // no data to add close pop-up when click save no message show
console.log("organizCheck=>", organizCheck);
// console.log("organizationData.value.length=>", organizationData.value.length);
if (organizCheck == true) {
// console.log(node.organizationId);
console.log("Call API13");
showLoader();
isShowEditTree.value = true; //end prepare for tricker LazyLoad
await http
.put(config.API.editTreeOrgDraft(node.organizationId), {
organizationId: node.organizationId, // GUID ของหน่วยงานที่ต้องการแก้ไขข้อมูล มีส่งไปใน uri ด้วย
organizationOrganizationId:
organizationDataEdit.value?.organizationOrganizationId,
organizationShortNameId:
organizationDataEdit.value?.organizationShortNameId,
organizationTypeId: organizationDataEdit.value?.organizationTypeId,
organizationLevelId: organizationDataEdit.value?.organizationLevelId,
organizationTelExternalId:
organizationDataEdit.value?.organizationExternalPhoneId,
organizationTelInternalId:
organizationDataEdit.value?.organizationInternalPhoneId,
organizationFaxId: organizationDataEdit.value?.organizationFaxId,
organizationOrder: organizationDataEdit.value?.organizationOrder,
organizationUserNote: organizationDataEdit.value?.organizationUserNote,
agency: organizationDataEdit.value?.agency,
government: organizationDataEdit.value?.government,
department: organizationDataEdit.value?.department,
pile: organizationDataEdit.value?.pile,
organizationStatusId: organizationDataEdit.value?.organizationStatusId,
isActive: organizationDataEdit.value?.isActive,
})
.then(async (res) => {
success($q, "บันทึกข้อมูลร่างสำเร็จ");
//reload children nodes by setExpanded mother node
const nodeSplit = await node.keyId.split("-");
const nodeDelete = await nodeSplit.splice(0, nodeSplit.length - 1);
const nodeJoin = await nodeDelete.join("-");
qtreeEdit.value.setExpanded(nodeJoin, true);
})
.catch((e) => {
console.log(e);
console.log(e.response);
messageError($q, e);
})
.finally(async () => {
hideLoader();
popupEditSelectedOrganization.value = false;
await isTreeHasDraft();
});
} else {
console.log("validation fail"); // or no data to add");
}
isShowEditTree.value = true;
};
/**Edit ตำแหน่ง ในโครงสร้าง
* API3
* @param node node that you want to edit data
*/
const editPositionStructure = async (node: any) => {
isShowEditTree.value = false; //start prepare for tricker LazyLoad
// console.log("positionData.value", positionData.value);
// console.log("Selectednode.keyId", node.keyId);
// console.log("PrarentNode.keyId", node.keyId.slice(0, -2));
let positionCheck: Boolean = false;
await positionForm.value
?.validate()
.then((e: Boolean) => (positionCheck = e));
if (positionCheck == true) {
console.log("Call API3");
showLoader();
isShowEditTree.value = true; //end prepare for tricker LazyLoad
await http
.put(config.API.editTreePositionDraft(node.organizationPositionId), {
positionMasterId: positionData.value[0].positionMasterId,
positionUserNote: positionData.value[0].positionUserNote,
isActive: positionData.value[0].isActive,
isCondition: positionData.value[0].isCondition,
conditionNote: positionData.value[0].conditionNote,
})
.then(async (res) => {
success($q, "บันทึกข้อมูลร่างสำเร็จ");
//reload children nodes by setExpanded mother node
const nodeSplit = await node.keyId.split("-");
const nodeDelete = await nodeSplit.splice(0, nodeSplit.length - 1);
const nodeJoin = await nodeDelete.join("-");
qtreeEdit.value.setExpanded(nodeJoin, true);
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
popupEditSelectedPosition.value = false;
await isTreeHasDraft();
});
} else {
console.log("validation fail"); // or no data to add");
}
isShowEditTree.value = true;
};
/**ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
*/
const clickHistory = async () => {
modalHistory.value = true;
// rowsHistory.value = rawHistory.value.filter((f: any) => f.id == row.id);
showLoader();
await http
.get(config.API.getTreeHistory)
.then((res) => {
let data = res.data.result;
rowsHistory.value = [];
// version.value = "published";
data.map((e: any) => {
rowsHistory.value.push({
detail: e.detail,
editUser: e.createdFullName,
editDate: e.createdAt,
});
// if (e.isPublished == false) {
// version.value = "draft";
// }
});
})
.catch((e) => {
rowsHistory.value.splice(0);
manageApiErrorMsg(e);
// messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
/**Check Error Code 404 before return error message
* Data not found is not error for GET method so do nothing
* @param catchE throw catch error message (e)
*/
const manageApiErrorMsg = (catchE: any) => {
if (catchE.response.status == 404 || catchE.response.data.status == 404) {
//Data not found is not error for GET method so do nothing
return;
// } else if (
// catchE.response.data.status == 400 ||
// catchE.response.data.status == 403 ||
// catchE.response.data.status == 404
// ) {
// //ใส่เป็น error กลางๆ ถ้ามีเคสให้เห็นมากขึ้น ถึงจะแยกข้อความได้
// modalError(q, "พบข้อผิดพลาด", "ไม่พบข้อมูล");
} else {
messageError($q, catchE);
}
};
</script>
<style>
.pointer:hover {
cursor: pointer;
background-color: #f4f4f4;
}
.q-tree__node-header {
padding: 0px;
margin-top: 0px;
border-radius: 4px;
outline: 0;
}
/* .q-tree__node--selected .q-tree__node-header-content {
border: 1px solid #02a998c0;
border-radius: 4px;
} */
.topCard {
z-index: 50;
position: absolute;
left: 35px;
}
.my-custom-toggle {
border: 1px solid #02a998;
}
.pageSK {
z-index: 30;
}
/* mouse over link */
.abc:hover {
color: #ff00ff;
}
.btn-absolute {
z-index: 50;
position: absolute;
left: 200px;
top: 30px;
}
.q-header {
z-index: 40;
}
.page-relative {
position: relative;
}
.my-list {
padding: 10px 10px;
}
.my-card {
width: 100%;
max-width: 160px;
}
.sub-card {
height: 100%;
max-height: 265px;
}
.cardNum {
border-radius: 5px;
}
.fc-direction-ltr .fc-daygrid-event.fc-event-end,
.fc-direction-rtl .fc-daygrid-event.fc-event-start {
padding-left: 5px;
}
.btnShadow {
box-shadow: 0 1px 2px rgb(0 0 0 / 10%), 3px 3px 7px 1px rgba(95, 95, 95, 0.15) !important;
}
.texttop {
font-size: 18px;
font-weight: 500;
}
.textSub {
font-size: 0.8rem;
}
.btnline {
border: 1px solid #c8d3dba4;
}
.q-tree {
color: #c8d3db;
}
</style>