From a20d2561d2a458e9aac73aaa14b5384fdb3dda11 Mon Sep 17 00:00:00 2001 From: Kritkhanin Anantakul <65160144@go.buu.ac.th> Date: Sun, 23 Mar 2025 20:05:37 +0700 Subject: [PATCH] fix page and gantt --- src/components/GanttChart/AddQueueDialog.vue | 52 +++--- src/components/GanttChart/GanttChart.vue | 156 ++++++++++-------- src/components/GanttChart/PrioritySetting.vue | 36 +--- src/components/GanttChart/StockConfig.vue | 65 ++++---- src/components/GanttChart/ganttChart.css | 1 + src/components/ProductionTargetTable.vue | 8 +- src/services/page.ts | 27 +-- src/services/stockConfig.ts | 5 +- src/stores/page.ts | 16 +- src/types/Page.ts | 8 +- 10 files changed, 179 insertions(+), 195 deletions(-) diff --git a/src/components/GanttChart/AddQueueDialog.vue b/src/components/GanttChart/AddQueueDialog.vue index 766a2ab..1646b56 100644 --- a/src/components/GanttChart/AddQueueDialog.vue +++ b/src/components/GanttChart/AddQueueDialog.vue @@ -1,5 +1,6 @@ <template> - <div class="add-queue-dialog-overlay" v-if="visible"> + <transition name="fade"> + <div class="add-queue-dialog-overlay" v-if="visible"> <div class="add-queue-dialog"> <h3 class="white-text">{{ isEditing ? "Edit Queue" : "Add New Queue" }}</h3> <form @submit.prevent="handleSubmit"> @@ -55,11 +56,6 @@ <input v-model.number="form.producedQuantity" class="border-input" type="number" required /> </div> - <div class="form-group"> - <label class="white-text">Page ID:</label> - <input v-model.number="form.pageID" class="border-input" type="number" readonly /> - </div> - <div class="dialog-buttons"> <button type="submit" class="primary-btn"> {{ isEditing ? "Save Changes" : "Add" }} @@ -68,7 +64,8 @@ </div> </form> </div> - </div> + </div> + </transition> </template> <script setup lang="ts"> @@ -76,6 +73,7 @@ import { reactive, ref, watch, onMounted, computed } from 'vue'; import { useMachineStore } from '@/stores/machine'; import { useOrderStore } from '@/stores/order'; import { useQueueStore } from '@/stores/queue'; +import { usePageContextStore } from '@/stores/pageContext'; import type { Queue } from '@/types/Queue'; const props = defineProps<{ @@ -88,6 +86,7 @@ const emit = defineEmits<{ (e: 'close'): void; }>(); +const pageContext = usePageContextStore(); const machineStore = useMachineStore(); const orderStore = useOrderStore(); const queueStore = useQueueStore(); @@ -110,19 +109,21 @@ const form = reactive({ status: "Pending", bottleSize: "600 ml", producedQuantity: null as number | null, - pageID: Number(props.currentPage), + pageID: pageContext.currentPage, }); -// ฟังก์ชันแปลงเวลาให้เข้ากับ datetime-local +// ให้ form.pageID อัปเดตอัตโนมัติเมื่อ currentPage เปลี่ยน +watch(() => pageContext.currentPage, (newVal) => { + form.pageID = newVal; +}); + +// แปลงเวลา ISO → datetime-local format function formatDateTime(dateTime: string | Date): string { if (!dateTime) return ""; - - // ถ้า dateTime เป็น Date ให้แปลงเป็น ISO String ก่อน if (dateTime instanceof Date) { return dateTime.toISOString().slice(0, 16); } - - return dateTime.replace(" ", "T"); // แปลง "2025-01-01 09:00" เป็น "2025-01-01T09:00" + return dateTime.replace(" ", "T"); } // โหลดข้อมูล queueItem เมื่อ Edit @@ -130,8 +131,6 @@ watch( () => props.queueItem, (newQueueItem) => { if (newQueueItem) { - console.log("🛠 queueItem received:", newQueueItem); - isEditing.value = true; form.machineID = newQueueItem.machineID ?? null; form.orderID = newQueueItem.orderID ?? null; @@ -140,7 +139,7 @@ watch( form.status = newQueueItem.status; form.bottleSize = newQueueItem.bottleSize; form.producedQuantity = newQueueItem.producedQuantity; - form.pageID = newQueueItem.pageID ?? Number(props.currentPage); + form.pageID = newQueueItem.pageID ?? pageContext.currentPage; } else { isEditing.value = false; resetForm(); @@ -150,7 +149,6 @@ watch( ); function closeDialog() { - console.log("🔴 Closing Dialog... Emitting 'close' event"); resetForm(); emit("close"); } @@ -163,13 +161,11 @@ function resetForm() { form.status = "Pending"; form.bottleSize = "600 ml"; form.producedQuantity = null; - form.pageID = Number(props.currentPage); + form.pageID = pageContext.currentPage; isEditing.value = false; } function handleSubmit() { - console.log("🚀 Submitting Form:", form); - if (!form.machineID || !form.orderID || !form.startTime || !form.finishTime || !form.status || !form.bottleSize || !form.producedQuantity) { console.warn("⚠️ กรุณากรอกข้อมูลให้ครบทุกช่อง!"); return; @@ -191,22 +187,21 @@ function handleSubmit() { queueStore .updateQueue(props.queueItem.QueueID, payload) .then(() => { - console.log("✅ Queue updated successfully!", payload); closeDialog(); }) .catch((error) => console.error("❌ Error updating queue:", error)); } else { queueStore .addQueue(payload) - .then(() => { - console.log("✅ Queue added successfully!", payload); + .then(async () => { + await queueStore.fetchQueues(); // ✅ ดึงข้อมูลใหม่แทน push เพื่อความครบ closeDialog(); }) .catch((error) => console.error("❌ Error adding queue:", error)); } } -</script> +</script> <style scoped> .add-queue-dialog-overlay { position: fixed; @@ -291,4 +286,13 @@ function handleSubmit() { border-color: #4299e1; box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); } + +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.3s ease; +} +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} </style> diff --git a/src/components/GanttChart/GanttChart.vue b/src/components/GanttChart/GanttChart.vue index 445a0ce..be1272a 100644 --- a/src/components/GanttChart/GanttChart.vue +++ b/src/components/GanttChart/GanttChart.vue @@ -7,12 +7,10 @@ <!-- ปุ่มจัดเรียงและเพิ่มระยะห่าง --> <div class="gantt-buttons"> <MakequeueBtn @click="openAddQueueDialog" /> - <SettingBtn class="mr-4"/> + <SettingBtn class="mr-4" /> </div> </div> - - <!-- Gantt Chart UI --> <div class="gantt-chart"> <!-- Header: Time Scale --> @@ -27,24 +25,44 @@ <!-- Rows: แสดงเครื่องจักรจาก Machine Store --> <div class="rows"> - <div v-for="machine in machineStore.machines" :key="machine.MachineID" class="row" - :data-machine-id="machine.MachineID" @dragover.prevent="onDragOver($event)" - @drop="onDrop($event, machine.MachineID)"> + <div + v-for="machine in machineStore.machines" + :key="machine.MachineID" + class="row" + :data-machine-id="machine.MachineID" + @dragover.prevent="onDragOver($event)" + @drop="onDrop($event, machine.MachineID)" + > <div class="machine-label"> {{ machine.name }} </div> <div class="row-timeline"> <!-- เส้นแนวตั้ง (Grid Lines) --> - <div v-for="hour in hours" :key="'line-' + hour" class="vertical-line" :style="getLineStyle(hour)"></div> - - <!-- แสดง Queue ที่ตรงกับวันที่ (selectedDate), Page, และ Machine --> - <div v-for="item in filteredQueue(machine.MachineID)" :key="item.QueueID" class="order" - :class="{ faded: draggingQueue && draggingQueue.QueueID === item.QueueID }" :style="getQueueStyle(item)"> + <div + v-for="hour in hours" + :key="'line-' + hour" + class="vertical-line" + :style="getLineStyle(hour)" + ></div> + + <!-- แสดง Queue ที่ตรงกับวันที่ (selectedDate), Page (pagenum), และ Machine --> + <div + v-for="item in filteredQueue(machine.MachineID)" + :key="item.QueueID" + class="order" + :class="{ faded: draggingQueue && draggingQueue.QueueID === item.QueueID }" + :style="getQueueStyle(item)" + > <!-- Handle สำหรับ Resize ด้านซ้าย --> <div class="resize-handle left" @mousedown="onResizeStart($event, item, 'left')"></div> <!-- ส่วนกลางของ Order ใช้สำหรับลาก และเปิด Dialog เมื่อคลิก --> - <div class="order-content" draggable="true" @dragstart="onDragStart($event, item)" - @dragend="onDragEnd($event, item)" @click.stop="openQueueDialog(item)"> + <div + class="order-content" + draggable="true" + @dragstart="onDragStart($event, item)" + @dragend="onDragEnd($event, item)" + @click.stop="openQueueDialog(item)" + > {{ item.orderID }} ({{ getTimeString(item.startTime) }} - {{ getTimeString(item.finishTime) }}) </div> <!-- Handle สำหรับ Resize ด้านขวา --> @@ -56,8 +74,7 @@ <!-- Ghost Queue (ขณะลาก/resize) --> <div v-if="ghostQueue" class="drag-ghost" :style="ghostStyle"> - {{ ghostQueue.orderID }} ({{ getTimeString(ghostQueue.startTime) }} - {{ getTimeString(ghostQueue.finishTime) - }}) + {{ ghostQueue.orderID }} ({{ getTimeString(ghostQueue.startTime) }} - {{ getTimeString(ghostQueue.finishTime) }}) </div> <v-divider :thickness="7"></v-divider> @@ -65,10 +82,19 @@ <!-- Pagination --> <div class="pagination-container"> <div class="pagination"> - <button v-for="p in pages" :key="p" :class="['page-btn', { active: p === currentPage }]" - @click="currentPage = p" @contextmenu.prevent="onPageRightClick(p, $event)"> + <button + v-for="p in pages" + :key="p" + :class="['page-btn', { active: p === currentPage }]" + @click="currentPage = p" + @contextmenu.prevent="onPageRightClick(p, $event)" + > {{ p }} - <button v-if="pageToShowDelete === p" class="delete-btn" @click.stop="deletePage(p)"> + <button + v-if="pageToShowDelete === p" + class="delete-btn" + @click.stop="deletePage(p)" + > Delete </button> </button> @@ -81,12 +107,21 @@ <v-icon>mdi-plus</v-icon> </v-btn> </div> - <AddQueueDialog :visible="showAddDialog" :queueItem="selectedQueueItem" :currentPage="currentPage" - @close="closeAddQueueDialog" /> + <AddQueueDialog + :visible="showAddDialog" + :queueItem="selectedQueueItem" + :currentPage="currentPage" + @close="closeAddQueueDialog" + /> </div> - <OrderDialog v-if="selectedQueueItem && !showAddDialog" :queueItem="selectedQueueItem" - :color="getQueueColor(selectedQueueItem.orderID)" @close="closeQueueDialog" @edit="openAddQueueDialogForEdit" - @delete="handleDelete" /> + <OrderDialog + v-if="selectedQueueItem && !showAddDialog" + :queueItem="selectedQueueItem" + :color="getQueueColor(selectedQueueItem.orderID)" + @close="closeQueueDialog" + @edit="openAddQueueDialogForEdit" + @delete="handleDelete" + /> </div> </div> </template> @@ -97,9 +132,8 @@ import { useQueueStore } from '@/stores/queue'; import { useMachineStore } from '@/stores/machine'; import { usePageStore } from '@/stores/page'; import { usePageContextStore } from '@/stores/pageContext'; - -import { useDateStore } from '@/stores/dateStore' -import { storeToRefs } from 'pinia' +import { useDateStore } from '@/stores/dateStore'; +import { storeToRefs } from 'pinia'; import GanttCalendar from './GanttCalendar.vue'; import OrderDialog from './OrderDialog.vue'; @@ -108,24 +142,24 @@ import MakequeueBtn from './MakequeueBtn.vue'; import SettingBtn from './SettingBtn.vue'; import './ganttChart.css'; -// ใช้ store สำหรับ Queue และ Machine +// Stores const queueStore = useQueueStore(); const machineStore = useMachineStore(); const pageStore = usePageStore(); - -const dateStore = useDateStore() -const { currentDate: selectedDate } = storeToRefs(dateStore) - +const dateStore = useDateStore(); +const { currentDate: selectedDate } = storeToRefs(dateStore); const pageContext = usePageContextStore(); + +// ใช้ currentPage เป็น pagenum จาก pageContext const currentPage = computed({ get: () => pageContext.currentPage, - set: (val) => pageContext.currentPage = val, + set: (val) => (pageContext.currentPage = val), }); // เมื่อเข้าหน้า ให้ดึงข้อมูลจาก backend onMounted(() => { machineStore.fetchMachines(); - queueStore.fetchQueues() + queueStore.fetchQueues(); pageStore.fetchPages(); }); @@ -134,7 +168,6 @@ const showAddDialog = ref(false); const startTime = ref('06:00'); const endTime = ref('20:00'); - const draggingQueue = ref<any | null>(null); const dragOffset = ref(0); const resizingQueue = ref<any | null>(null); @@ -169,7 +202,8 @@ const formattedQueues = computed(() => { status: q.status || "Unknown", bottleSize: q.bottleSize || "Unknown", producedQuantity: q.producedQuantity || 0, - pageNumber: q.page?.PageID || 0, + // เปลี่ยนจาก PageID เป็น pagenum + pageNumber: q.page?.pagenum || 0, })); }); @@ -180,7 +214,7 @@ function convertToLocalTime(utcString: string): string { } // Pagination & Dialog -const pages = computed(() => pageStore.pages.map(p => p.PageID)); +const pages = computed(() => pageStore.pages.map(p => p.pagenum)); const pageToShowDelete = ref<number | null>(null); const selectedQueueItem = ref<any | null>(null); @@ -209,15 +243,12 @@ function openAddQueueDialog() { selectedQueueItem.value = null; showAddDialog.value = true; } - function openAddQueueDialogForEdit(queueItem: any) { selectedQueueItem.value = { ...queueItem }; showAddDialog.value = true; } - function handleDelete(queueItem: { QueueID: number; }) { if (!queueItem) return; - queueStore .deleteQueue(queueItem.QueueID) .then(() => { @@ -226,13 +257,11 @@ function handleDelete(queueItem: { QueueID: number; }) { }) .catch((error) => console.error(`❌ Error deleting queue:`, error)); } - function closeAddQueueDialog() { showAddDialog.value = false; selectedQueueItem.value = null; } - function formatHour(hour: number): string { return (hour < 10 ? '0' + hour : hour) + ':00'; } @@ -245,13 +274,14 @@ function getTimeString(dateTimeStr: string): string { function filteredQueue(machineID: number) { return formattedQueues.value.filter(q => { - const queueDate = getDateString(q.startTime) + if (!q || !q.startTime || !q.finishTime) return false; + const queueDate = getDateString(q.startTime); return ( q.machineID === machineID && q.pageNumber === currentPage.value && - queueDate === selectedDate.value // ✅ ใช้จาก store แล้ว - ) - }) + queueDate === selectedDate.value + ); + }); } const colorMap: Record<string, string> = {}; @@ -383,7 +413,6 @@ function onDragOverGlobal(event: DragEvent) { }); if (closestRow) { - // ใช้ dataset เพื่อดึง machine id const machineIDString = (closestRow as HTMLElement).dataset.machineId; if (machineIDString) { ghostQueue.value.machineID = parseInt(machineIDString, 10); @@ -391,7 +420,6 @@ function onDragOverGlobal(event: DragEvent) { ghostStyle.top = (closestRow as HTMLElement).getBoundingClientRect().top + 'px'; } - ghostStyle.left = snappedLeft + 'px'; ghostStyle.width = snappedWidth + 'px'; } @@ -407,12 +435,11 @@ async function onDragEnd(event: DragEvent, item: any) { console.log(`🔄 Updating Queue ${item.QueueID} after drag...`); item.startTime = ghostQueue.value.startTime; item.finishTime = ghostQueue.value.finishTime; - // ใช้ ghostQueue.value.machine.MachineID แทนการอ่าน machineID จาก ghostQueue.value const newMachineID = ghostQueue.value.machine?.MachineID || item.machineID; await queueStore.updateQueue(item.QueueID, { startTime: item.startTime, finishTime: item.finishTime, - machine: { MachineID: newMachineID, name: '' } + MachineID: newMachineID, }); ghostQueue.value = null; ghostStyle.display = 'none'; @@ -420,27 +447,21 @@ async function onDragEnd(event: DragEvent, item: any) { } async function onDrop(event: DragEvent, newMachineID: number) { event.preventDefault(); - if (!draggingQueue.value || !ghostQueue.value) return; - console.log(`🔄 Dropped Queue ${draggingQueue.value.QueueID} to Machine ${newMachineID}`); - draggingQueue.value.startTime = ghostQueue.value.startTime; draggingQueue.value.finishTime = ghostQueue.value.finishTime; - draggingQueue.value.machineID = newMachineID; // ✅ อัปเดต MachineID - + draggingQueue.value.machineID = newMachineID; try { await queueStore.updateQueue(draggingQueue.value.QueueID, { startTime: draggingQueue.value.startTime, finishTime: draggingQueue.value.finishTime, - MachineID: newMachineID, // ✅ ส่งค่าไป Backend + MachineID: newMachineID, }); - console.log(`✅ Queue ${draggingQueue.value.QueueID} updated to Machine ${newMachineID}`); } catch (error) { console.error(`❌ Error updating queue:`, error); } - ghostQueue.value = null; ghostStyle.display = 'none'; draggingQueue.value = null; @@ -485,7 +506,7 @@ async function onResizeEnd() { console.log(`🔄 Updating Queue ${resizingQueue.value.QueueID} after resize...`); await queueStore.updateQueue(resizingQueue.value.QueueID, { startTime: ghostQueue.value.startTime, - finishTime: ghostQueue.value.finishTime + finishTime: ghostQueue.value.finishTime, }); resizingQueue.value = null; resizeDirection.value = null; @@ -494,10 +515,12 @@ async function onResizeEnd() { document.removeEventListener('mousemove', onResizing); document.removeEventListener('mouseup', onResizeEnd); } + // Pagination Functions async function addPage() { if (pageStore.pages.length < 10) { await pageStore.addPage(); + await pageStore.fetchPages(); // 👈 โหลดหน้าทั้งหมดใหม่ } else { alert('Maximum of 10 pages allowed.'); } @@ -506,14 +529,15 @@ function onPageRightClick(page: number, event: MouseEvent) { event.preventDefault(); pageToShowDelete.value = page; } -async function deletePage(pageID: number) { - await pageStore.removePage(pageID); - if (currentPage.value === pageID) { - const remaining = pageStore.pages.map(p => p.PageID); +async function deletePage(pageNum: number) { + await pageStore.removePage(pageNum); + await pageStore.fetchPages(); // 👈 โหลดหน้าทั้งหมดใหม่ + + if (currentPage.value === pageNum) { + const remaining = pageStore.pages.map(p => p.pagenum); currentPage.value = remaining.length > 0 ? remaining[0] : 1; } - pageToShowDelete.value = null; } @@ -529,8 +553,4 @@ onMounted(() => { onBeforeUnmount(() => { document.removeEventListener('click', onDocumentClick); }); - -function closeDialog() { - throw new Error('Function not implemented.'); -} -</script> +</script> \ No newline at end of file diff --git a/src/components/GanttChart/PrioritySetting.vue b/src/components/GanttChart/PrioritySetting.vue index 9818e06..306101d 100644 --- a/src/components/GanttChart/PrioritySetting.vue +++ b/src/components/GanttChart/PrioritySetting.vue @@ -1,30 +1,16 @@ <script setup lang="ts"> -import { ref, onMounted, computed, watch } from 'vue'; +import { ref, onMounted, computed } from 'vue'; import { useOrderPriorityStore } from '@/stores/orderPriority'; -import { usePageContextStore } from '@/stores/pageContext'; const orderPriorityStore = useOrderPriorityStore(); -const pageContextStore = usePageContextStore(); -// current page จาก global context store -const pageID = computed(() => pageContextStore.currentPage); - -// โหลด priorities ตอน mount และเมื่อ page เปลี่ยน +// โหลดลำดับความสำคัญทั้งหมดเมื่อ component mount onMounted(() => { - if (pageID.value) { - orderPriorityStore.fetchWithFilter(undefined, pageID.value); - } -}); - -watch(pageID, (newVal) => { - if (newVal) { - orderPriorityStore.fetchWithFilter(undefined, newVal); - } + orderPriorityStore.fetchWithFilter(); }); const orders = computed(() => { return orderPriorityStore.priorities - .filter((p) => p.page?.PageID === pageID.value) .sort((a, b) => a.priority - b.priority) .map((p) => ({ id: p.order.OrderID, @@ -54,15 +40,10 @@ const handleDrop = async (targetOrder: any) => { updatedList.splice(targetIndex, 0, moved); const payload = { - pages: [ - { - pageID: pageID.value, - configs: updatedList.map((order, index) => ({ - id: order.orderPriorityID, - priority: index + 1, - })), - }, - ], + priorities: updatedList.map((order, index) => ({ + id: order.orderPriorityID, + priority: index + 1, + })), }; await orderPriorityStore.updateMany(payload); @@ -73,7 +54,7 @@ const handleDrop = async (targetOrder: any) => { <template> <v-card class="pa-5" style="background-color: #333647; border-radius: 15px; min-height: 280px;"> <p class="text-center font-weight-bold mb-2" style="color: white; font-size: 20px;"> - ลำดับความสำคัญ (Page {{ pageID }}) + ลำดับความสำคัญ </p> <transition-group name="list" tag="div"> @@ -92,6 +73,7 @@ const handleDrop = async (targetOrder: any) => { </v-card> </template> + <style scoped> .order-item { background-color: white; diff --git a/src/components/GanttChart/StockConfig.vue b/src/components/GanttChart/StockConfig.vue index 8294993..1d2f0f3 100644 --- a/src/components/GanttChart/StockConfig.vue +++ b/src/components/GanttChart/StockConfig.vue @@ -50,20 +50,14 @@ <script setup> import { ref, onMounted } from 'vue'; import { useStockConfigStore } from '@/stores/stockConfig'; -import { usePageContextStore } from '@/stores/pageContext'; const stockConfigStore = useStockConfigStore(); -const pageContextStore = usePageContextStore(); // ดึงข้อมูล StockConfig จาก backend เมื่อ component mount onMounted(() => { - const pageId = pageContextStore.currentPage; - if (pageId != null) { - console.log('📄 Current Page ID:', pageId); - stockConfigStore.fetchStockConfigs(pageId).then(() => { - console.log('✅ ดึงได้:', stockConfigStore.stockConfigs); - }); - } + stockConfigStore.fetchStockConfigs().then(() => { + console.log('✅ ดึงได้:', stockConfigStore.stockConfigs); + }); }); // สำหรับ drag & drop @@ -78,41 +72,42 @@ function handleDragOver(event) { } async function handleDrop(targetConfig) { - if (!draggedConfig.value || draggedConfig.value.StockConfigID === targetConfig.StockConfigID) + if ( + !draggedConfig.value || + draggedConfig.value.StockConfigID === targetConfig.StockConfigID + ) return; - const configs = stockConfigStore.stockConfigs; - const draggedIndex = configs.findIndex( + const originalConfigs = stockConfigStore.stockConfigs; + const draggedIndex = originalConfigs.findIndex( (c) => c.StockConfigID === draggedConfig.value.StockConfigID ); - const targetIndex = configs.findIndex( + const targetIndex = originalConfigs.findIndex( (c) => c.StockConfigID === targetConfig.StockConfigID ); - const [removed] = configs.splice(draggedIndex, 1); - configs.splice(targetIndex, 0, removed); - - // ✅ หลัง reorder ใน frontend แล้วส่งอัปเดตไป backend - const pageID = pageContextStore.currentPage; - const payload = { - pages: [ - { - PageID: pageID, - configs: configs.map((config, index) => ({ - id: config.StockConfigID, - priorityLevel: index + 1, - targetStockLevel: config.targetStockLevel, - status: config.status, - })), - }, - ], - }; - - await stockConfigStore.batchUpdateStockConfigs(payload); - draggedConfig.value = null; -} + if (draggedIndex === -1 || targetIndex === -1) return; + + const newConfigs = [...originalConfigs]; + const [removed] = newConfigs.splice(draggedIndex, 1); + newConfigs.splice(targetIndex, 0, removed); + + const updatedPayload = newConfigs.map((config, index) => ({ + id: config.StockConfigID, + priorityLevel: index + 1, + targetStockLevel: config.targetStockLevel, + status: config.status, + })); + await stockConfigStore.batchUpdateStockConfigs(updatedPayload); + stockConfigStore.stockConfigs = newConfigs.map((c, idx) => ({ + ...c, + priorityLevel: idx + 1, + })); + + draggedConfig.value = null; +} // Toggle สำหรับ "ไม่ทำการผลิตเผื่อ" const isProductionSpare = ref(false); diff --git a/src/components/GanttChart/ganttChart.css b/src/components/GanttChart/ganttChart.css index 726fa49..0175699 100644 --- a/src/components/GanttChart/ganttChart.css +++ b/src/components/GanttChart/ganttChart.css @@ -76,6 +76,7 @@ display: flex; align-items: center; z-index: 1; + transition: left 0.1s ease, width 0.1s ease; } .order-content { diff --git a/src/components/ProductionTargetTable.vue b/src/components/ProductionTargetTable.vue index 52e1ab8..7c7b139 100644 --- a/src/components/ProductionTargetTable.vue +++ b/src/components/ProductionTargetTable.vue @@ -145,13 +145,9 @@ function blockInvalidKeys(event: KeyboardEvent) { <style scoped> .custom-table { - font-size: 16px; -} -.tiny-input input { - font-size: 12px !important; - padding: 2px 4px !important; - height: 24px !important; + font-size: 12px; } + .fade-check { animation: fadeOut 1s ease-out forwards; } diff --git a/src/services/page.ts b/src/services/page.ts index bfd1d48..b388d47 100644 --- a/src/services/page.ts +++ b/src/services/page.ts @@ -1,41 +1,26 @@ import http from './http'; import type { Page } from '@/types/Page'; -/** - * ดึงรายการ Page ทั้งหมด - */ export async function listPages(): Promise<Page[]> { const { data } = await http.get('/pages'); return data; } -/** - * ดึง Page รายการเดียว - */ -export async function getPage(id: number): Promise<Page> { - const { data } = await http.get(`/pages/${id}`); +export async function getPage(pagenum: number): Promise<Page> { + const { data } = await http.get(`/pages/${pagenum}`); return data; } -/** - * สร้าง Page ใหม่ (ไม่ต้องส่ง payload) - */ export async function createPage(): Promise<Page> { const { data } = await http.post('/pages'); return data; } -/** - * อัปเดต Page - */ -export async function updatePage(id: number, payload: Partial<Page>): Promise<Page> { - const { data } = await http.put(`/pages/${id}`, payload); +export async function updatePage(pagenum: number, payload: Partial<Page>): Promise<Page> { + const { data } = await http.put(`/pages/${pagenum}`, payload); return data; } -/** - * ลบ Page - */ -export async function deletePage(id: number): Promise<void> { - await http.delete(`/pages/${id}`); +export async function deletePage(pagenum: number): Promise<void> { + await http.delete(`/pages/${pagenum}`); } diff --git a/src/services/stockConfig.ts b/src/services/stockConfig.ts index 7510c61..e82fd6f 100644 --- a/src/services/stockConfig.ts +++ b/src/services/stockConfig.ts @@ -43,9 +43,8 @@ export async function updateStockConfig(id: number, payload: UpdateStockConfigDt /** * อัปเดตแบบหลายรายการ (batch) */ -export async function updateManyStockConfigs(payload: BatchUpdateManyStockConfigDto): Promise<any> { - const { data } = await http.put('/stock-config/batch', payload); - return data; +export async function updateManyStockConfigs(payload: BatchUpdateManyStockConfigDto) { + return await http.patch('/stock-config/batch', payload); // ✅ เปลี่ยนจาก put → patch } /** diff --git a/src/stores/page.ts b/src/stores/page.ts index ce84526..005cb1c 100644 --- a/src/stores/page.ts +++ b/src/stores/page.ts @@ -20,11 +20,11 @@ export const usePageStore = defineStore('page', () => { } } - async function fetchPage(id: number): Promise<Page | null> { + async function fetchPage(pagenum: number): Promise<Page | null> { loading.value = true; error.value = null; try { - return await pageService.getPage(id); + return await pageService.getPage(pagenum); } catch (e: any) { error.value = e.message || 'Unknown Error'; return null; @@ -46,12 +46,12 @@ export const usePageStore = defineStore('page', () => { } } - async function editPage(id: number, payload: Partial<Page>) { + async function editPage(pagenum: number, payload: Partial<Page>) { loading.value = true; error.value = null; try { - const updated = await pageService.updatePage(id, payload); - const index = pages.value.findIndex(p => p.PageID === id); + const updated = await pageService.updatePage(pagenum, payload); + const index = pages.value.findIndex(p => p.pagenum === pagenum); if (index !== -1) pages.value[index] = updated; } catch (e: any) { error.value = e.message || 'Unknown Error'; @@ -60,12 +60,12 @@ export const usePageStore = defineStore('page', () => { } } - async function removePage(id: number) { + async function removePage(pagenum: number) { loading.value = true; error.value = null; try { - await pageService.deletePage(id); - pages.value = pages.value.filter(p => p.PageID !== id); + await pageService.deletePage(pagenum); + pages.value = pages.value.filter(p => p.pagenum !== pagenum); } catch (e: any) { error.value = e.message || 'Unknown Error'; } finally { diff --git a/src/types/Page.ts b/src/types/Page.ts index b030667..bcc6434 100644 --- a/src/types/Page.ts +++ b/src/types/Page.ts @@ -1,5 +1,7 @@ +// types/Page.ts export interface Page { PageID: number; - createdAt: string; // ISO string - updatedAt?: string; // ISO string (nullable) -} \ No newline at end of file + pagenum: number; + createdAt: string; + updatedAt?: string; +} -- GitLab