diff --git a/env.d.ts b/env.d.ts index 11f02fe2a..33cd2182c 100644 --- a/env.d.ts +++ b/env.d.ts @@ -1 +1,2 @@ /// +declare module 'quasar-ui-q-draggable-table'; \ No newline at end of file diff --git a/package.json b/package.json index 403f6f025..cc3443f41 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "node-sass": "^9.0.0", "npm-run-all": "^4.1.5", "prettier": "^2.7.1", + "quasar-ui-q-draggable-table": "^1.0.1", "sass": "^1.69.4", "start-server-and-test": "^1.15.2", "typescript": "~4.7.4", diff --git a/src/main.ts b/src/main.ts index 2926f9112..79578a04c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,7 +2,10 @@ import { createApp, defineAsyncComponent } from "vue"; import App from "./App.vue"; import router from "./router"; import { Dialog, Notify, Quasar, Loading } from "quasar"; -import quasarUserOptions from "./quasar-user-options"; +import "./quasar-user-options"; + +import qDraggableTable from 'quasar-ui-q-draggable-table'; +import 'quasar-ui-q-draggable-table/dist/index.css'; import "quasar/src/css/index.sass"; import th from "quasar/lang/th"; @@ -29,6 +32,7 @@ app.config.globalProperties.$filters = filters; app.use(router); app.use(pinia); +app.use(qDraggableTable); app.use( Quasar, diff --git a/src/modules/01_metadataNew/components/insignia/InsigniaDetail.vue b/src/modules/01_metadataNew/components/insignia/InsigniaDetail.vue index db71f6c5e..e9d957565 100644 --- a/src/modules/01_metadataNew/components/insignia/InsigniaDetail.vue +++ b/src/modules/01_metadataNew/components/insignia/InsigniaDetail.vue @@ -17,7 +17,6 @@ const router = useRouter(); const route = useRoute(); const $q = useQuasar(); const store = useInsigniaDataStore(); -const row = ref(); const mixin = useCounterMixin(); const { date2Thai, messageError, hideLoader, showLoader } = mixin; const id = ref(route.params.id.toString()); @@ -40,9 +39,10 @@ async function fetchData(id: string) { } onMounted(async () => { - fetchData(id.value); + await fetchData(id.value); }); + { - + diff --git a/src/modules/01_metadataNew/components/insignia/InsigniaList.vue b/src/modules/01_metadataNew/components/insignia/InsigniaList.vue index 227ac7657..cf7090275 100644 --- a/src/modules/01_metadataNew/components/insignia/InsigniaList.vue +++ b/src/modules/01_metadataNew/components/insignia/InsigniaList.vue @@ -5,12 +5,20 @@ import { useCounterMixin } from "@/stores/mixin"; import { useRouter, useRoute } from "vue-router"; import { useInsigniaDataStore } from "@/modules/01_metadataNew/stores/InsigniaStore"; import dialogHeader from "@/components/DialogHeader.vue"; +import TableDraggable from "@/modules/01_metadataNew/components/insignia/TableDraggable.vue"; import { useQuasar } from "quasar"; import http from "@/plugins/http"; import config from "@/app.config"; const store = useInsigniaDataStore(); const router = useRouter(); const mixin = useCounterMixin(); + +const props = defineProps({ + fetchData: { + type: Function, + default: ()=>"", + } +}) const { date2Thai, dialogRemove, @@ -22,17 +30,14 @@ const { const $q = useQuasar(); const columns = ref([ { - name: "level", + name: "no", align: "left", label: "ลำดับ", - sortable: true, - field: "level", + sortable: false, + field: "no", headerStyle: "font-size: 14px; width:0px", style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, - { name: "name", align: "left", @@ -143,7 +148,7 @@ const shortNameRef = ref(null); const dialogStatus = ref(""); const editId = ref(""); const visibleColumns = ref([ - "level", + "no", "name", "shortName", "insigniaType", @@ -164,24 +169,24 @@ function validateForm() { onSubmit(); } -async function fetchData(id: string) { - showLoader(); - await http - .get(config.API.insigniaTypeNewId(id)) - .then(async (res) => { - insigniaTypeId.value = res.data.result.name; - store.fetchData(res.data.result.insignias, res.data.result.name); - }) - .catch((err) => { - messageError($q, err); - }) - .finally(() => { - hideLoader(); - }); -} -onMounted(async () => { - fetchData(id.value); -}); +// async function fetchData(id: string) { +// showLoader(); +// await http +// .get(config.API.insigniaTypeNewId(id)) +// .then(async (res) => { +// insigniaTypeId.value = res.data.result.name; +// store.fetchData(res.data.result.insignias, res.data.result.name); +// }) +// .catch((err) => { +// messageError($q, err); +// }) +// .finally(() => { +// hideLoader(); +// }); +// } +// onMounted(async () => { +// fetchData(id.value); +// }); async function onSubmit() { if (name.value.length > 0 && shortName.value.length > 0) { @@ -209,7 +214,7 @@ async function addData() { note: note.value == "" ? "-" : note.value, insigniaTypeId: id.value, }); - fetchData(id.value); + props.fetchData(id.value); } async function editData(idData: string) { @@ -220,17 +225,18 @@ async function editData(idData: string) { note: note.value == "" ? "-" : note.value, insigniaTypeId: id.value, }); - fetchData(id.value); + props.fetchData(id.value); } async function deleteData(idData: string) { await http.delete(config.API.insigniaNewId(idData)); - fetchData(id.value); + props.fetchData(id.value); } import { defineEmits } from "vue"; const emit = defineEmits(["nameType"]); +const dialogOrder = ref(false); @@ -250,6 +256,16 @@ const emit = defineEmits(["nameType"]); > เพิ่มข้อมูล + (dialogOrder = true)" + > + จัดลำดับการแสดงผล + + @@ -293,8 +309,11 @@ const emit = defineEmits(["nameType"]); - - + + + {{ props.rowIndex + 1 }} + + +import { ref, watch } from "vue"; +import type { QTableProps } from "quasar"; +import { useCounterMixin } from "@/stores/mixin"; +import { useRouter, useRoute } from "vue-router"; +import { useInsigniaDataStore } from "@/modules/01_metadataNew/stores/InsigniaStore"; +import dialogHeader from "@/components/DialogHeader.vue"; +import { useQuasar } from "quasar"; +import DialogHeader from "@/components/DialogHeader.vue"; + +import http from "@/plugins/http"; +import config from "@/app.config"; +const store = useInsigniaDataStore(); +const mixin = useCounterMixin(); +const { dialogRemove, dialogConfirm, showLoader, hideLoader, messageError } = + mixin; +const $q = useQuasar(); +const route = useRoute(); +const modal = defineModel("modal", { type: Boolean }); +const columns = ref([ + { + name: "name", + required: true, + label: "ชื่อเครื่องราชฯ", + align: "left", + field: "name", + sortable: true, + }, + { + name: "shortName", + align: "center", + label: "ชื่อย่อ", + field: "shortName", + }, + { + name: "insigniaType", + align: "left", + label: "ลำดับชั้นเครื่องราชฯ", + field: "insigniaType", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + sortable: true, + }, +]); + +function onDrop(from: any, to: any) { + onDropRow(from, to); +} + +const rows = ref([]); +function onDropRow(from: any, to: any) { + rows.value.splice(to, 0, rows.value.splice(from, 1)[0]); +} + +async function save() { + const dataPost = await rows.value.map((obj:any) => { + return obj.id; +}); + console.log("post data===>", dataPost); + modal.value = false + + // showLoader(); + // await http + // .put(config.API.insigniaTypeNewId(id), dataPost) + // .then(async (res) => { + // }) + // .catch((err) => { + // messageError($q, err); + // }) + // .finally(() => { + // hideLoader(); + store.row = rows.value + // }); +} + +async function onSubmit() { + dialogConfirm($q, async () => { + save(); + }); +} + +watch(modal, () => { + if (modal.value === true) { + // rows.value = store.row; + rows.value = [...store.row]; // ดึงมาใช้ sort แล้วใน store ไม่เปลี่ยน + } +}); + + + + + + + + + + + + + + + + + + บันทึกข้อมูล + + + + + + diff --git a/src/modules/01_metadataNew/stores/InsigniaStore.ts b/src/modules/01_metadataNew/stores/InsigniaStore.ts index f127e4f90..dbcfb026d 100644 --- a/src/modules/01_metadataNew/stores/InsigniaStore.ts +++ b/src/modules/01_metadataNew/stores/InsigniaStore.ts @@ -9,11 +9,11 @@ import { useCounterMixin } from "@/stores/mixin"; const { date2Thai } = useCounterMixin(); export const useInsigniaDataStore = defineStore("insigniaData", () => { - const row = ref(); + const row = ref([]); function fetchData(data: DataResponse[], insigniaType?: string) { - data.forEach((row, index) => { - row.level = index + 1; - }); + // data.forEach((row, index) => { + // row.level = index + 1; + // }); const list = data.map((e) => ({ ...e, insigniaType: insigniaType, diff --git a/src/modules/02_organizationalNew/components/DialogFormPosition.vue b/src/modules/02_organizationalNew/components/DialogFormPosition.vue index 78381a629..dafa9c308 100644 --- a/src/modules/02_organizationalNew/components/DialogFormPosition.vue +++ b/src/modules/02_organizationalNew/components/DialogFormPosition.vue @@ -8,6 +8,9 @@ import type { FormDataPosition, FormPositionRef, DataOption, + FormPositionSelect, + RowDetailPositions, + ListMenu, } from "@/modules/02_organizationalNew/interface/index/Main"; const props = defineProps({ @@ -15,23 +18,56 @@ const props = defineProps({ close: Function, }); +const isReadonly = ref(false); // อ่านได้อย่างเดียว const $q = useQuasar(); const mixin = useCounterMixin(); const { dialogConfirm } = mixin; +const selected = ref([]); +const search = ref(""); +const type = ref("positionName"); +const typeOps = ref([ + { id: "positionName", name: "ตำแหน่งในสายงาน" }, + { id: "positionField", name: "สายงาน" }, + { id: "positionType", name: "ประเภทตำแหน่ง" }, + { id: "positionLevel", name: "ระดับตำแหน่ง" }, + { id: "positionExecutive", name: "ตำแหน่งทางการบริหาร" }, + { id: "positionExecutiveField", name: "ด้านทางการบริหาร" }, + { id: "positionArea", name: "ด้าน/สาขา" }, +]); -const rows = ref([]); +const listMenu = ref([ + { + label: "คัดลอก", + icon: "mdi-content-copy", + type: "copy", + color: "orange", + }, +]); + +const rows = ref([]); +const rowsPositionSelect = ref([]); const ocLevelOp = ref([]); const prefixNoRef = ref(null); const positionNoRef = ref(null); const formData = reactive({ + shortName: "สกจ.", prefixNo: "", positionNo: "", suffixNo: "", confirm: false, }); +const formPositionSelect = reactive({ + positionName: "", + positionField: "", + positionType: "", + positionLevel: "", + positionExecutive: "", + positionExecutiveField: "", + positionArea: "", +}); /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ const objectPositionRef: FormPositionRef = { prefixNo: prefixNoRef, @@ -39,60 +75,89 @@ const objectPositionRef: FormPositionRef = { }; const columns = ref([ - { - name: "no", - align: "left", - label: "ลำดับ", - sortable: false, - field: "no", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - }, - { - name: "positionType", - align: "left", - label: "ประเภทตำเเหน่ง", - sortable: true, - field: "positionType", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - }, - { - name: "positionLevel", - align: "left", - label: "ระดับตำแหน่ง ด้าน/สาขา", - sortable: true, - field: "positionLevel", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - }, - { - name: "positionAdmin", - align: "left", - label: "ตำแหน่งทางการบริหาร", - sortable: true, - field: "positionAdmin", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - }, - { - name: "other", - align: "left", - label: "ฯลฯ", - sortable: true, - field: "other", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - }, - - ]); - const visibleColumns = ref([ - "no", - "positionType", - "positionLevel", - "positionAdmin", - "other", - ]); + { + name: "no", + align: "left", + label: "ลำดับ", + sortable: false, + field: "no", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionName", + align: "left", + label: "ตำแหน่งในสายงาน", + sortable: true, + field: "positionName", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionField", + align: "left", + label: "สายงาน", + sortable: true, + field: "positionField", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionType", + align: "left", + label: "ประเภทตำเเหน่ง", + sortable: true, + field: "positionType", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionLevel", + align: "left", + label: "ระดับตำแหน่ง", + sortable: true, + field: "positionLevel", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionExecutive", + align: "left", + label: "ตำแหน่งทางการบริหาร", + sortable: true, + field: "positionExecutive", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionExecutiveField", + align: "left", + label: "ด้านทางการบริหาร", + sortable: true, + field: "positionExecutiveField", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "positionArea", + align: "left", + label: "ด้าน/สาขา", + sortable: true, + field: "positionArea", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, +]); +const visibleColumns = ref([ + "no", + "positionName", + "positionField", + "positionType", + "positionLevel", + "positionExecutive", + "positionExecutiveField", + "positionArea", +]); /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ function validateForm() { @@ -112,27 +177,120 @@ function validateForm() { } } +/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ +function validateFormPositionEdit() { + // const hasError = []; + // for (const key in objectPositionRef) { + // if (Object.prototype.hasOwnProperty.call(objectPositionRef, key)) { + // const property = objectPositionRef[key]; + // if (property.value && typeof property.value.validate === "function") { + // const isValid = property.value.validate(); + // hasError.push(isValid); + // } + // } + // } + // if (hasError.every((result) => result === true)) { + onSubmitSelectEdit(); + // } else { + // } +} + /** ฟังชั่น บันทึก */ function onSubmit() { dialogConfirm($q, () => { console.log(formData); }); } +/** ฟังชั่น บันทึก */ +function onSubmitSelectEdit() { + dialogConfirm($q, () => { + console.log(formPositionSelect); + }); +} + +/** update เมื่อเปลี่ยน option */ +function updateSelect() { + search.value = ""; +} + +/** input ค้นหา */ +const searchRef = ref(null); +async function searchInput() { + searchRef.value.validate(); + if (!searchRef.value.hasError) { + // จำลอง + const dataList = [ + { + positionName: "test1", + positionField: "test1", + positionType: "test1", + positionLevel: "test1", + positionExecutive: "test1", + positionExecutiveField: "test1", + positionArea: "test1", + }, + { + positionName: "test2", + positionField: "test2", + positionType: "test2", + positionLevel: "test2", + positionExecutive: "test2", + positionExecutiveField: "test2", + positionArea: "test2", + }, + { + positionName: "test3", + positionField: "test3", + positionType: "test3", + positionLevel: "test3", + positionExecutive: "test3", + positionExecutiveField: "test3", + positionArea: "test3", + }, + ]; + rowsPositionSelect.value = dataList; + } +} + +/** + * คัดลอกข้อมูล + * @param data ข้อมูลตำแหน่ง + */ +function copyDetiail(data: RowDetailPositions) { + formPositionSelect.positionName = data.positionName; + formPositionSelect.positionField = data.positionField; + formPositionSelect.positionType = data.positionType; + formPositionSelect.positionLevel = data.positionLevel; + formPositionSelect.positionExecutive = data.positionExecutive; + formPositionSelect.positionExecutiveField = data.positionExecutiveField; + formPositionSelect.positionArea = data.positionArea; +} + +/** + * ส่งค่า css ออกไปตามเงื่อนไข + * @param val true/false + */ +function inputEdit(val: boolean) { + return { + "full-width cursor-pointer inputgreen ": val, + "full-width cursor-pointer inputgreen": !val, + }; +} watch( () => props.modal, () => { if (props.modal === true) { - ocLevelOp.value = [ - { - id: "id1", - name: "id1", - }, - { - id: "id2", - name: "id2", - }, - ]; + } + } +); +watch( + () => selected.value, + () => { + if (selected.value.length > 0) { + rows.value = selected.value; + } else { + rows.value = []; } } ); @@ -140,101 +298,411 @@ watch( - - - - + + + - - - - - - - - - - - - - + + + + - - - + รายการตำแหน่ง + + + + + + + + + + + + + + + + + - {{ col.label }} - - - - - - - - {{ props.rowIndex + 1 }} - - - {{ col.value }} - - - - - - - - - + + + + {{ + col.label + }} + + + + + + + + {{ props.rowIndex + 1 }} + + + {{ col.value }} + + + + + + + + + + + + + + + + - - + + + + + เลือกตำแหน่ง + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ + col.label + }} + + + + + + + + + + + + {{ props.rowIndex + 1 }} + + + {{ props.prefix }} + + + {{ props.row.salary.toLocaleString() }} + + + {{ col.value }} + + + + + + + + + + + {{ + item.label + }} + + + + + + + + + + + + + + + + + + เลือกตำแหน่ง + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/02_organizationalNew/components/StructureDetail.vue b/src/modules/02_organizationalNew/components/StructureDetail.vue index 88847a66c..2068ed372 100644 --- a/src/modules/02_organizationalNew/components/StructureDetail.vue +++ b/src/modules/02_organizationalNew/components/StructureDetail.vue @@ -103,13 +103,13 @@ watch( - ภายนอก {{ formData.orgPhoneEx }} + {{ formData.orgPhoneEx ? `ภายนอก ${formData.orgPhoneEx}`:'' }} - ภายใน {{ formData.orgPhoneIn }} + {{ formData.orgPhoneIn ? `ภายใน ${formData.orgPhoneIn}`:'' }} diff --git a/src/modules/02_organizationalNew/interface/index/Main.ts b/src/modules/02_organizationalNew/interface/index/Main.ts index 4c0bdf7b7..1235db9a1 100644 --- a/src/modules/02_organizationalNew/interface/index/Main.ts +++ b/src/modules/02_organizationalNew/interface/index/Main.ts @@ -25,6 +25,7 @@ interface FormDataAgency { } interface FormDataPosition { + shortName: string; prefixNo: string; positionNo: string; suffixNo: string; @@ -71,7 +72,27 @@ interface HistoryType { orgRevisionName: string; orgRevisionIsCurrent: boolean; orgRevisionIsDraft: boolean; - orgRevisionCreatedAt: any; + orgRevisionCreatedAt: Date | string; +} + +interface FormPositionSelect { + positionName: string; + positionField: string; + positionType: string; + positionLevel: string; + positionExecutive: string; + positionExecutiveField: string; + positionArea: string; +} + +interface RowDetailPositions { + positionName: string + positionField: string + positionType: string + positionLevel: string + positionExecutive: string + positionExecutiveField: string + positionArea: string } export type { Pagination, @@ -85,4 +106,6 @@ export type { FormNewStructureRef, HistoryType, ListMenu, + FormPositionSelect, + RowDetailPositions }; diff --git a/tsconfig.json b/tsconfig.json index 7f365145e..3a8d5e262 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,8 @@ ], "compilerOptions": { + "typeRoots": ["./typings", "./node_modules/@types"], + "types": ["quasar-ui-q-draggable-table"], /* other configs */ "paths": { "@/*": [
ภายนอก {{ formData.orgPhoneEx }}
{{ formData.orgPhoneEx ? `ภายนอก ${formData.orgPhoneEx}`:'' }}
ภายใน {{ formData.orgPhoneIn }}
{{ formData.orgPhoneIn ? `ภายใน ${formData.orgPhoneIn}`:'' }}