Merge branch 'develop' into devTee

This commit is contained in:
setthawutttty 2024-02-02 14:53:26 +07:00
commit 11d0b9b874
18 changed files with 1944 additions and 60 deletions

View file

@ -1,3 +1,231 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "prefix",
align: "left",
label: "คำนำหน้าชื่อ",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const prefix = ref<string>("");
const prefixRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("คำนำหน้าชื่อ");
const visibleColumns = ref<string[]>([
"prefix",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "ว่าที่ร้อยตรี",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "นางสาว",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "นาย",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
คำนำหนาช
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="prefix"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -1,3 +1,231 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "rank",
align: "left",
label: "ยศ",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const rank = ref<string>("");
const rankRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("ยศ");
const visibleColumns = ref<string[]>([
"rank",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "ยศ 1",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "ยศ 2",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "ยศ 3",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
ยศ
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="rank"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -1,3 +1,231 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "bloodGroup",
align: "left",
label: "กลุ่มเลือด",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const bloodGroup = ref<string>("");
const bloodGroupRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("กลุ่มเลือด");
const visibleColumns = ref<string[]>([
"bloodGroup",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "A",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "AB",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "O",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
กลมเลอด
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="bloodGroup"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -1,3 +1,231 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "gender",
align: "left",
label: "เพศ",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const gender = ref<string>("");
const genderRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("เพศ");
const visibleColumns = ref<string[]>([
"gender",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "ชาย",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "หญิง",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "เพศทางเลือก",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
เพศ
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="gender"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -1,3 +1,238 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "religion",
align: "left",
label: "ศาสนา",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const religion = ref<string>("");
const religionRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("ศาสนา");
const visibleColumns = ref<string[]>([
"religion",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "อิสลาม",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "พุทธ",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "ขงจื้อ",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
{
id: "4",
name: "คริสต์",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
ศาสนา
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="religion"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -1,3 +1,238 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useRouter } from "vue-router";
import { usePersonalDataStore } from "@/modules/01_metadataNew/stores/personalStore";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
import DialogForm from "@/modules/01_metadataNew/components/personal/DialogForm.vue";
const store = usePersonalDataStore();
const router = useRouter();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const columns = ref<QTableProps["columns"]>([
{
name: "relationship",
align: "left",
label: "สถานภาพ",
sortable: true,
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdateFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "lastUpdateFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
const $q = useQuasar();
const filterKeyword = ref<string>("");
const dialog = ref<boolean>(false);
const relationship = ref<string>("");
const relationshipRef = ref<any>(null);
const dialogStatus = ref<string>("");
const personalName = ref<string>("สถานภาพ");
const visibleColumns = ref<string[]>([
"relationship",
"createdAt",
"lastUpdatedAt",
"lastUpdateFullName",
]);
function fetchData() {
const data = [
{
id: "1",
name: "เคยสมรสแต่ไม่ทราบสถานภาพสมรส",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "สาวิตรี ศรีสมัย",
},
{
id: "2",
name: "สมรส",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "System Administrator",
},
{
id: "3",
name: "แยกกันอยู่",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
{
id: "4",
name: "โสด",
createdAt: new Date(),
lastUpdatedAt: new Date(),
lastUpdateFullName: "คณะกรรมการ ตรวจรับ",
},
];
store.fetchData(data);
}
onMounted(async () => {
fetchData();
});
</script>
<template>
สถานภาพ
</template>
<q-toolbar style="padding: 0">
<q-btn
flat
round
color="primary"
icon="add"
@click.stop="
() => {
dialogStatus = 'create';
dialog = true;
}
"
>
<q-tooltip> เพมขอม </q-tooltip>
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-input outlined dense v-model="filterKeyword" label="ค้นหา"></q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<d-table
ref="table"
:columns="columns"
:rows="store.row"
:filter="filterKeyword"
row-key="name"
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">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:props="props"
class="cursor-pointer"
@click.stop="onclickDetail(props.row.id)"
>
<q-td v-for="col in props.cols" :key="col.id">
<div>
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-btn
color="grey"
flat
dense
round
size="14px"
icon="more_vert"
@click.stop
>
<q-menu>
<q-list dense>
<q-item
v-close-popup
clickable
@click.stop="
() => {
dialogStatus = 'edit';
dialog = true;
}
"
>
<q-item-section>
<div class="row items-center white">
<q-icon name="o_edit" color="positive" />
<span class="q-ml-sm">แกไข</span>
</div>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section
@click="dialogRemove($q, async () => {})"
v-close-popup
>
<div class="row items-center white">
<q-icon name="mdi-trash-can-outline" color="negative" />
<span class="q-ml-sm">ลบ</span>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
<DialogForm
v-model:dialog="dialog"
v-model:data="relationship"
v-model:personalName="personalName"
v-model:dialogStatus="dialogStatus"
/>
</template>

View file

@ -0,0 +1,86 @@
<script setup lang="ts">
import { ref } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import dialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar";
const $q = useQuasar();
const mixin = useCounterMixin();
const { dialogRemove, dialogConfirm } = mixin;
const dataRef = ref<any>(null);
const data = defineModel<string>("data", {
required: true,
});
const personalName = defineModel<string>("personalName");
const dialogStatus = defineModel<string>("dialogStatus");
const dialog = defineModel<boolean>("dialog");
function closeDialog() {
dialog.value = false;
}
function validateForm() {
dataRef.value.validate();
onSubmit();
}
async function onSubmit() {
if (data.value.length > 0) {
dialogConfirm(
$q,
async () => {
closeDialog();
data.value = "";
},
"ยืนยันการบันทึกข้อมูล",
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
);
}
}
</script>
<template>
<q-dialog v-model="dialog" class="dialog" persistent>
<q-card style="min-width: 350px" class="bg-grey-11">
<form @submit.prevent="validateForm">
<q-card-section class="flex justify-between" style="padding: 0">
<dialog-header
:tittle="dialogStatus == 'edit' ? 'แก้ไขข้อมูล' : 'เพิ่มข้อมูล'"
:close="closeDialog"
/>
</q-card-section>
<q-separator color="grey-4" />
<q-card-section class="q-pa-none">
<q-input
ref="dataRef"
outlined
v-model="data"
:label="personalName"
dense
lazy-rules
borderless
class="col-12 bg-white q-ma-md"
:rules="[(val) => val.length > 0 || 'กรุณากรอก' + personalName]"
hide-bottom-space
/>
</q-card-section>
<q-card-actions align="right">
<q-btn
id="onSubmit"
type="submit"
dense
unelevated
label="บันทึก"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>

View file

@ -0,0 +1,25 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import type {
DataResponse,
DataRow,
} from "../interface/response/insignia/Insignia";
import { useCounterMixin } from "@/stores/mixin";
const { date2Thai } = useCounterMixin();
export const usePersonalDataStore = defineStore("PersonalData", () => {
const row = ref<DataRow[]>([]);
function fetchData(data: DataResponse[]) {
const list = data.map((e) => ({
...e,
createdAt: e.createdAt ? date2Thai(e.createdAt) : "",
lastUpdatedAt: e.lastUpdatedAt ? date2Thai(e.lastUpdatedAt) : "",
}));
row.value = list;
}
return {
fetchData,
row,
};
});

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

@ -90,26 +90,33 @@ function validateForm() {
/** ฟังชั่น บันทึก */
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
http
.post(config.API.createOrganization, formData)
.then((res) => {
status.value = true;
store.typeOrganizational = "draft";
store.draftId = res.data.result.id;
success($q, "บันทึกข้อมูลสำเร็จ");
// props.fetchActive?.();
})
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
modal.value = await false;
await close();
await hideLoader();
});
});
dialogConfirm(
$q,
() => {
showLoader();
http
.post(config.API.createOrganization, formData)
.then((res) => {
status.value = true;
store.typeOrganizational = "draft";
store.draftId = res.data.result.id;
success($q, "บันทึกข้อมูลสำเร็จ");
// props.fetchActive?.();
})
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
modal.value = await false;
await close();
await hideLoader();
});
},
"ยืนยันการเพิ่มโครงสร้าง",
store.draftId
? "คุณมีแบบร่างอยู่หากคุณกดยืนยันระบบจะทำการลบแบบร่างเดิมและสร้างแบบร่างใหม่ ต้องการยืนยันการเพิ่มโครงสร้างนี้ใช่หรือไม่?"
: "ต้องการยืนยันการเพิ่มโครงสร้างนี้ใช่หรือไม่?"
);
}
function close() {

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"
/>
@ -195,8 +196,31 @@ watch(
</div>
<div v-else class="col-12 row items-center">
<!-- summary -->
<div
v-if="nodeId"
class="row col-12 justify-between list-summary q-gutter-xs bg-grey-1"
>
<div class="row col q-pa-sm item">
<div class="ellipsis">ตำแหนงทงหมด</div>
<q-space />
<q-badge color="secondary" :label="store.sumPosition.total" />
</div>
<div class="row col q-pa-sm item bg-grey-1">
<div class="ellipsis">ตำแหนงทคนครอง</div>
<q-space />
<q-badge color="primary" :label="store.sumPosition.use" />
</div>
<div class="row col q-pa-sm item bg-grey-1">
<div class="ellipsis">ตำแหนงวาง</div>
<q-space />
<q-badge color="red" :label="store.sumPosition.vacant" />
</div>
</div>
<TableView
v-if="nodeId !== ''"
v-model:nodeTree="nodeTree"
v-model:orgLevel="orgLevel"
v-model:treeId="nodeId"
v-model:reqMaster="reqMaster"
@ -204,6 +228,7 @@ watch(
v-model:posMaster="posMaster"
:fetchDataTable="fetchDataTable"
:filterKeyword="filterKeyword"
:fetchDataTree="fetchDataTree"
/>
<q-banner v-else class="q-pa-lg col-12 text-center">
@ -217,4 +242,10 @@ watch(
</div>
</template>
<style scoped></style>
<style scoped>
.list-summary .item {
border: 1px solid rgb(231, 231, 231);
border-radius: 4px;
background-color: white;
}
</style>

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,19 +95,27 @@ 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>("");
const updateSelected = (id: string, level: number) => {
store.treeId = id;
store.level = level;
if (id === nodeId.value) {
const updateSelected = (data: any) => {
store.treeId = data.orgTreeId;
store.level = data.orgLevel;
if (data.orgTreeId === nodeId.value) {
nodeId.value = "";
} else {
nodeId.value = id ? id : "";
id && props.fetchDataTable?.(id, level, true);
nodeId.value = data.orgTreeId ? data.orgTreeId : "";
data.orgTreeId &&
props.fetchDataTable?.(data.orgTreeId, data.orgLevel, true);
store.getSumPosition({
totalPosition: data.totalPosition,
totalPositionCurrentUse: data.totalPositionCurrentUse,
totalPositionCurrentVacant: data.totalPositionCurrentVacant,
totalPositionNextUse: data.totalPositionNextUse,
totalPositionNextVacant: data.totalPositionNextVacant,
});
}
};
@ -352,7 +361,7 @@ onMounted(async () => {});
<div
class="row items-center q-px-xs q-pt-xs q-gutter-sm"
@click="updateSelected(prop.node.orgTreeId, prop.node.orgLevel)"
@click="updateSelected(prop.node)"
>
<!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree-->
<div>

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" :fetchDataTable="props.fetchDataTable"/>
<!-- ดลำด -->
<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 };

View file

@ -3,8 +3,16 @@ interface DataActive {
activeName: string;
draftId: string;
draftName: string;
isPublic: boolean,
orgPublishDate: Date | null,
isPublic: boolean;
orgPublishDate: Date | null;
}
interface SumPosition {
totalPosition: number;
totalPositionCurrentUse: number;
totalPositionCurrentVacant: number;
totalPositionNextUse: number;
totalPositionNextVacant: number;
}
interface OrgTree {
@ -80,7 +88,7 @@ interface Position {
interface PosMaster {
id: string; // id อัตรากำลัง posmaster
orgShortname: string; // อักษรย่อตำแหน่ง
orgShortname: string; // อักษรย่อตำแหน่ง
posMasterNoPrefix: string; // Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)
posMasterNo: number | string; // เลขที่ตำแหน่ง เป็นตัวเลข
posMasterNoSuffix: string | null; // Suffix หลังเลขที่ตำแหน่ง เช่น ช.
@ -114,7 +122,7 @@ interface Position2 {
interface PosMaster2 {
id: string; // id อัตรากำลัง posmaster
orgShortname: string; // อักษรย่อตำแหน่ง
orgShortname: string; // อักษรย่อตำแหน่ง
posMasterNoPrefix: string; // Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)
posMasterNo: number | string; // เลขที่ตำแหน่ง เป็นตัวเลข
posMasterNoSuffix: string | null; // Suffix หลังเลขที่ตำแหน่ง เช่น ช.
@ -144,4 +152,5 @@ export type {
PosMaster2,
Position,
Position2,
SumPosition
};

View file

@ -1,10 +1,10 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { reactive, ref } from "vue";
/** importType*/
import type {
DataActive,
Position,
SumPosition,
PosMaster,
} from "@/modules/02_organizationalNew/interface/response/organizational";
@ -19,6 +19,23 @@ export const useOrganizational = defineStore("organizationalStore", () => {
const level = ref<number>();
const isPublic = ref<boolean>(false);
const orgPublishDate = ref<Date | null>(null);
const sumPosition = reactive({
total: 0,
use: 0,
vacant: 0,
});
function getSumPosition(data: SumPosition) {
sumPosition.total = data.totalPosition;
sumPosition.use =
typeOrganizational.value == "draft"
? data.totalPositionNextUse
: data.totalPositionCurrentUse;
sumPosition.vacant =
typeOrganizational.value == "draft"
? data.totalPositionNextVacant
: data.totalPositionCurrentVacant;
}
function fetchDataActive(data: DataActive) {
activeId.value = data.activeId;
@ -100,5 +117,7 @@ export const useOrganizational = defineStore("organizationalStore", () => {
isPublic,
orgPublishDate,
fetchPosMaster,
sumPosition,
getSumPosition,
};
});

View file

@ -240,7 +240,7 @@ onMounted(async () => {
</q-btn-dropdown>
</q-btn-group>
<q-btn-dropdown color="green" label="ประวัติโครงสร้าง">
<q-btn-dropdown color="green" label="เพิ่มโครงสร้าง">
<q-list>
<q-item
dense