From 7a7042c3f5efb1739628201d38f709a6b7ae991b Mon Sep 17 00:00:00 2001 From: Kritkhanin Anantakul <65160144@go.buu.ac.th> Date: Tue, 18 Mar 2025 16:41:16 +0700 Subject: [PATCH] all gantt service store / connect fontend backend / fix calendar format/ fix some ui --- src/components/GanttChart/GanttChart.vue | 358 +++++++++++------------ 1 file changed, 172 insertions(+), 186 deletions(-) diff --git a/src/components/GanttChart/GanttChart.vue b/src/components/GanttChart/GanttChart.vue index 839de80..a732f38 100644 --- a/src/components/GanttChart/GanttChart.vue +++ b/src/components/GanttChart/GanttChart.vue @@ -4,9 +4,8 @@ <div class="gantt-header"> <!-- Calendar: เชื่อมกับ selectedDate --> <GanttCalendar v-model:modelValue="selectedDate" /> - <!-- ปุ่ม Make a queue พร้อม event listener --> - <MakequeueBtn @click="queueStore.makeQueue()" /> + <MakequeueBtn @click="openAddQueueDialog" /> </div> <!-- Gantt Chart UI --> @@ -21,31 +20,48 @@ </div> </div> - <!-- Rows: เครื่องจักรแต่ละตัว --> + <!-- Rows: แสดงเครื่องจักรจาก Machine Store --> <div class="rows"> - <div v-for="machine in machines" :key="machine.machineID" class="row" @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.machineID }} + {{ 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> + <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="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 ด้านขวา --> <div class="resize-handle right" @mousedown="onResizeStart($event, item, 'right')"></div> </div> @@ -53,10 +69,9 @@ </div> </div> - <!-- Ghost Queue (ขณะลาก) --> + <!-- 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> @@ -64,88 +79,81 @@ <!-- 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)"> Delete </button> </button> - - <!-- ปุ่มเพิ่มหน้า + (แบบปกติ) --> <button class="page-btn add-page" @click="addPage" :disabled="pages.length >= 10"> + </button> </div> - - <!-- ปุ่ม Add Queue อยู่ขวาสุด --> <div class="pagination-right"> <v-btn class="add-page-btn" @click="openAddQueueDialog" icon> <v-icon>mdi-plus</v-icon> </v-btn> </div> - - <!-- AddQueueDialog (สำหรับเพิ่ม/แก้ไข) --> - <AddQueueDialog :visible="showAddDialog" :queueItem="selectedQueueItem" @close="closeAddQueueDialog" - @add="handleAddQueue" @edit="handleEditQueue" /> + <AddQueueDialog + :visible="showAddDialog" + :queueItem="selectedQueueItem" + @close="closeAddQueueDialog" + @add="handleAddQueue" + @edit="handleEditQueue" + /> </div> - - <!-- Order Dialog (สำหรับดูรายละเอียดเพิ่มเติม) --> - <OrderDialog v-if="selectedQueueItem && !showAddDialog" :queueItem="selectedQueueItem" - :color="getQueueColor(selectedQueueItem.orderID)" @close="closeQueueDialog" @edit="openAddQueueDialogForEdit" - @delete="deleteQueueItem" /> + <OrderDialog + v-if="selectedQueueItem && !showAddDialog" + :queueItem="selectedQueueItem" + :color="getQueueColor(selectedQueueItem.orderID)" + @close="closeQueueDialog" + @edit="openAddQueueDialogForEdit" + @delete="deleteQueueItem" + /> </div> </div> </template> <script lang="ts" setup> import { ref, reactive, computed, onMounted, onBeforeUnmount, watch } from 'vue'; +import { useQueueStore } from '@/stores/queue'; +import { useMachineStore } from '@/stores/machine'; import GanttCalendar from './GanttCalendar.vue'; import OrderDialog from './OrderDialog.vue'; import AddQueueDialog from './AddQueueDialog.vue'; import MakequeueBtn from './MakequeueBtn.vue'; import './ganttChart.css'; -import { useQueueStore } from '@/stores/queue'; -import type { QueueItem } from '@/types/QueueItem'; - -interface Machine { - machineID: string; - name: string; -} - - +// ใช้ store สำหรับ Queue และ Machine const queueStore = useQueueStore(); +const machineStore = useMachineStore(); -// NOTE: ถ้าต้องการโหลดข้อมูลทันทีที่เข้าหน้านี้ ให้ un-comment ด้านล่าง +// เมื่อเข้าหน้า ให้ดึงข้อมูลจาก backend onMounted(() => { - + machineStore.fetchMachines(); + queueStore.fetchQueues().then(() => { + console.log("📌 Queues Loaded:", queueStore.queues); + }); }); -// State +// State สำหรับ Gantt Chart const showAddDialog = ref(false); -const selectedDate = ref('1/1/2025'); +const selectedDate = ref('2025-01-01'); const startTime = ref('08:00'); const endTime = ref('17:00'); -const machines = ref<Machine[]>([ - { machineID: 'MC1', name: 'เครื่องเป่าขวด' }, - { machineID: 'MC2', name: 'เครื่องเป่าขวด2' }, - { machineID: 'MC3', name: 'เครื่องสวมฉลาก' }, - { machineID: 'MC4', name: 'เครื่องบรรจุ+แพ็ค' }, -]); - -// ดึง ref ของ QueueItem[] จาก Store -const Queues = computed(() => queueStore.Queues.value); - -// Drag/Drop & Resize -const draggingQueue = ref<QueueItem | null>(null); +const draggingQueue = ref<any | null>(null); const dragOffset = ref(0); -const resizingQueue = ref<QueueItem | null>(null); +const resizingQueue = ref<any | null>(null); const resizeDirection = ref<string | null>(null); -const ghostQueue = ref<QueueItem | null>(null); +const ghostQueue = ref<any | null>(null); const ghostStyle = reactive({ position: 'fixed', top: '0px', @@ -162,19 +170,42 @@ const ghostStyle = reactive({ zIndex: 9999, }); +// แปลงข้อมูล Queue จาก backend ให้เข้ากับรูปแบบที่ Gantt Chart ใช้ +const formattedQueues = computed(() => { + return queueStore.queues.map(q => ({ + QueueID: q.QueueID, + orderID: q.order?.OrderID || "Unknown", + machineID: q.machine?.MachineID || 0, + machineName: q.machine?.name || "Unknown Machine", + startTime: q.startTime ? convertToLocalTime(q.startTime) : "Unknown", + finishTime: q.finishTime ? convertToLocalTime(q.finishTime) : "Unknown", + status: q.status || "Unknown", + bottleSize: q.bottleSize || "Unknown", + producedQuantity: q.producedQuantity || 0, + pageNumber: q.page?.PageID || 0, + })); +}); + +function convertToLocalTime(utcString: string): string { + const date = new Date(utcString); + date.setHours(date.getHours() + 7); + return date.toISOString().slice(0, 16).replace("T", " "); +} + // Pagination & Dialog const pages = ref<number[]>([1, 2]); const currentPage = ref(1); const pageToShowDelete = ref<number | null>(null); -const selectedQueueItem = ref<QueueItem | null>(null); - +const selectedQueueItem = ref<any | null>(null); -watch(() => queueStore.Queues.value, (newVal) => { - console.log("🔄 Queues updated in GanttChart.vue:", newVal); -}, { deep: true }); +watch( + () => queueStore.queues, + (newVal) => { + console.log("🔄 Queues updated in GanttChart.vue:", newVal); + }, + { deep: true } +); - -// Computed const hours = computed(() => { const startHour = parseInt(startTime.value.split(':')[0]); const endHour = parseInt(endTime.value.split(':')[0]); @@ -182,78 +213,51 @@ const hours = computed(() => { }); // Methods -function handleUpdateQueue(newQueue: QueueItem[]) { - console.log("Received new queue:", newQueue); - // อัปเดตลงใน store - Queues.value = newQueue; -} - -function openQueueDialog(item: QueueItem) { +function openQueueDialog(item: any) { selectedQueueItem.value = { ...item }; } - function closeQueueDialog() { selectedQueueItem.value = null; } - function openAddQueueDialog() { selectedQueueItem.value = null; showAddDialog.value = true; } - -function deleteQueueItem(item: QueueItem) { - // ลบคิวใน store - Queues.value = Queues.value.filter(q => q.queueID !== item.queueID); +function deleteQueueItem(item: any) { + queueStore.removeQueue(item.QueueID); closeQueueDialog(); } - -function openAddQueueDialogForEdit(queueItem: QueueItem) { +function openAddQueueDialogForEdit(queueItem: any) { selectedQueueItem.value = { ...queueItem }; showAddDialog.value = true; } - function closeAddQueueDialog() { showAddDialog.value = false; selectedQueueItem.value = null; } - -function handleAddQueue(newQueueItem: Omit<QueueItem, 'queueID'>) { - const newQueueID = Queues.value.length + 1; - Queues.value.push({ queueID: newQueueID, ...newQueueItem }); +async function handleAddQueue(newQueueItem: any) { + await queueStore.addQueue(newQueueItem); showAddDialog.value = false; } - -function handleEditQueue(updatedQueueItem: QueueItem) { - const index = Queues.value.findIndex(q => q.queueID === updatedQueueItem.queueID); - if (index !== -1) { - Queues.value.splice(index, 1, { ...updatedQueueItem }); - } +async function handleEditQueue(updatedQueueItem: any) { + await queueStore.editQueue(updatedQueueItem.QueueID, updatedQueueItem); selectedQueueItem.value = null; showAddDialog.value = false; } -// Utility Functions function formatHour(hour: number): string { return (hour < 10 ? '0' + hour : hour) + ':00'; } - function getDateString(dateTimeStr: string): string { return dateTimeStr.split(' ')[0]; } - function getTimeString(dateTimeStr: string): string { return dateTimeStr.split(' ')[1]; } -function filteredQueue(machineID: string) { - if (!queueStore.Queues?.values || typeof queueStore.Queues.values !== "function") { - console.warn("queueStore.Queues.values is not a function or is undefined"); - return []; - } - - return queueStore.Queues.filter(q => { +function filteredQueue(machineID: number) { + return formattedQueues.value.filter(q => { const queueDate = getDateString(q.startTime); - console.log(queueDate) return ( q.machineID === machineID && q.pageNumber === currentPage.value && @@ -262,59 +266,36 @@ function filteredQueue(machineID: string) { }); } - - - -const colorMap: Record<string, string> = {}; // Map เก็บสีของแต่ละ orderID - +const colorMap: Record<string, string> = {}; function getQueueColor(orderID: string | number): string { const key = String(orderID); - - // 🔴 ถ้าเป็น "ผลิตเผื่อ" → ใช้สีแดงพาสเทล - if (key === "ผลิตเผื่อ") { - return "#FFC1C1"; // Light Pastel Red - } - - // 💜 ถ้าเป็น "เปลี่ยนขนาด" → ใช้สีม่วงชมพูพาสเทล - if (key === "เปลี่ยนขนาด") { - return "#E1BEE7"; // Light Pastel Pink-Purple (Lavender) - } - - // ✅ ถ้ามีสีอยู่แล้ว ให้ใช้สีเดิม + if (key === "ผลิตเผื่อ") return "#FFC1C1"; + if (key === "เปลี่ยนขนาด") return "#E1BEE7"; if (colorMap[key]) return colorMap[key]; - - // 🌊 ถ้าเป็นคิวปกติ → ใช้สีธีมน้ำ const newColor = generateWaterPastel(); colorMap[key] = newColor; return newColor; } - function generateWaterPastel(): string { - // สุ่มเฉพาะสีโทนน้ำทะเล (ฟ้า, น้ำเงิน, เขียวมิ้นต์) const waterHues = [180, 190, 200, 210, 220, 230, 240]; const hue = waterHues[Math.floor(Math.random() * waterHues.length)]; return `hsl(${hue}, 60%, 80%)`; } - -function getQueueStyle(item: QueueItem) { +function getQueueStyle(item: any) { const start = getTimeString(item.startTime); const end = getTimeString(item.finishTime); const startDecimal = timeToDecimal(start); const endDecimal = timeToDecimal(end); - const totalHours = hours.value.length; // นับจำนวนชั่วโมงที่แสดง - - // คำนวณอัตราส่วนของตำแหน่งเริ่มต้นและสิ้นสุด ตามจำนวนชั่วโมงทั้งหมด + const totalHours = hours.value.length; const leftPercent = ((startDecimal - timeToDecimal(startTime.value)) / totalHours) * 100; const widthPercent = ((endDecimal - startDecimal) / totalHours) * 100; - - const backgroundColor = getQueueColor(item.orderID); // ใช้ฟังก์ชันที่แก้ไขแล้ว - - console.log(`Queue ${item.queueID}: orderID=${item.orderID}, color=${backgroundColor}`); - + const orderID = item.orderID || "Unknown"; + const backgroundColor = getQueueColor(orderID); + console.log(`Queue ${item.QueueID}: orderID=${orderID}, color=${backgroundColor}`); return { left: `${leftPercent}%`, width: `${widthPercent}%`, - backgroundColor: backgroundColor, // ใช้สีแดงพาสเทลหรือสีธีมน้ำ + backgroundColor, color: '#333', borderRadius: '10px', textAlign: 'center', @@ -327,51 +308,39 @@ function getQueueStyle(item: QueueItem) { boxShadow: '0px 4px 6px rgba(0, 0, 0, 0.1)', }; } - - - - function getLineStyle(hour: number) { - const totalHours = hours.value.length; // นับจำนวนชั่วโมงที่แสดง (เช่น 10 ช่อง) - const leftPercent = (hour - timeToDecimal(startTime.value)) / totalHours * 100; - + const totalHours = hours.value.length; + const leftPercent = ((hour - timeToDecimal(startTime.value)) / totalHours) * 100; return { left: `${leftPercent}%` }; } - function timeToDecimal(timeStr: string): number { - const [hours, minutes] = timeStr.split(':').map(Number); - return hours + minutes / 60; + const [h, m] = timeStr.split(':').map(Number); + return h + m / 60; } - function decimalToTime(decimal: number): string { - const hours = Math.floor(decimal); - const minutes = Math.round((decimal - hours) * 60); - return (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes); + const hrs = Math.floor(decimal); + const minutes = Math.round((decimal - hrs) * 60); + return (hrs < 10 ? '0' + hrs : hrs) + ':' + (minutes < 10 ? '0' + minutes : minutes); } // Drag/Drop & Resize Functions -function onDragStart(event: DragEvent, item: QueueItem) { +function onDragStart(event: DragEvent, item: any) { draggingQueue.value = item; const target = event.target as HTMLElement; const rect = target.getBoundingClientRect(); dragOffset.value = rect.width / 2; - const emptyImg = new Image(); emptyImg.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; event.dataTransfer?.setDragImage(emptyImg, 0, 0); - ghostQueue.value = { ...item }; ghostStyle.display = 'block'; - ghostStyle.backgroundColor = getQueueColor(item.orderID); - + ghostStyle.backgroundColor = getQueueColor(item.order?.OrderID || "Unknown"); document.addEventListener('dragover', onDragOverGlobal); document.addEventListener('dragend', onDragEndGlobal); } - function onDragOver(event: DragEvent) { event.preventDefault(); } - function onDragOverGlobal(event: DragEvent) { event.preventDefault(); const rowTimeline = document.querySelector('.row-timeline') as HTMLElement; @@ -389,7 +358,6 @@ function onDragOverGlobal(event: DragEvent) { const startDecimal = timeToDecimal(getTimeString(draggingQueue.value.startTime)); const endDecimal = timeToDecimal(getTimeString(draggingQueue.value.finishTime)); const duration = endDecimal - startDecimal; - let newStartDecimal = timelineStartDec + ratio * (timelineEndDec - timelineStartDec); newStartDecimal = Math.round(newStartDecimal * 2) / 2; let newEndDecimal = newStartDecimal + duration; @@ -407,11 +375,13 @@ function onDragOverGlobal(event: DragEvent) { ghostQueue.value.finishTime = newEndStr; } + // คำนวณตำแหน่ง ghost element const snappedRatioStart = (newStartDecimal - timelineStartDec) / (timelineEndDec - timelineStartDec); const snappedLeft = timelineRect.left + snappedRatioStart * timelineWidth; const snappedRatioEnd = (newEndDecimal - timelineStartDec) / (timelineEndDec - timelineStartDec); const snappedWidth = (snappedRatioEnd - snappedRatioStart) * timelineWidth; + // หาจุด row ที่ใกล้เคียงที่สุดและดึง machine id จาก attribute const rows = document.querySelectorAll('.row'); let closestRow: HTMLElement | null = null; let minDistance = Infinity; @@ -425,9 +395,10 @@ function onDragOverGlobal(event: DragEvent) { }); if (closestRow) { - const labelEl = closestRow.querySelector('.machine-label') as HTMLElement; - if (labelEl) { - ghostQueue.value!.machineID = labelEl.textContent?.trim() || ghostQueue.value!.machineID; + // ใช้ dataset เพื่อดึง machine id + const machineIDString = closestRow.dataset.machineId; + if (machineIDString) { + ghostQueue.value.machine = { MachineID: parseInt(machineIDString, 10) }; } ghostStyle.top = closestRow.getBoundingClientRect().top + 'px'; } @@ -442,38 +413,45 @@ function onDragEndGlobal() { draggingQueue.value = null; document.removeEventListener('dragend', onDragEndGlobal); } - -function onDragEnd(event: DragEvent, item: QueueItem) { +async function onDragEnd(event: DragEvent, item: any) { if (!ghostQueue.value) return; + console.log(`🔄 Updating Queue ${item.QueueID} after drag...`); item.startTime = ghostQueue.value.startTime; item.finishTime = ghostQueue.value.finishTime; - item.machineID = ghostQueue.value.machineID; - document.removeEventListener('dragover', onDragOverGlobal); + // ใช้ 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: '' } + }); ghostQueue.value = null; ghostStyle.display = 'none'; draggingQueue.value = null; } - -function onDrop(event: DragEvent, newMachine: string) { +async function onDrop(event: DragEvent, newMachineID: number) { event.preventDefault(); if (draggingQueue.value && ghostQueue.value) { draggingQueue.value.startTime = ghostQueue.value.startTime; draggingQueue.value.finishTime = ghostQueue.value.finishTime; - draggingQueue.value.machineID = newMachine; + draggingQueue.value.machine = { MachineID: newMachineID }; + await queueStore.updateQueue(draggingQueue.value.QueueID, { + startTime: draggingQueue.value.startTime, + finishTime: draggingQueue.value.finishTime, + machine: { MachineID: newMachineID, name: '' } + }); } ghostQueue.value = null; ghostStyle.display = 'none'; draggingQueue.value = null; } - -function onResizeStart(event: MouseEvent, item: QueueItem, direction: string) { +function onResizeStart(event: MouseEvent, item: any, direction: string) { event.preventDefault(); resizingQueue.value = item; resizeDirection.value = direction; document.addEventListener('mousemove', onResizing); document.addEventListener('mouseup', onResizeEnd); } - function onResizing(event: MouseEvent) { if (!resizingQueue.value) return; const rowTimeline = document.querySelector('.row-timeline') as HTMLElement; @@ -481,10 +459,8 @@ function onResizing(event: MouseEvent) { const timelineRect = rowTimeline.getBoundingClientRect(); const timelineWidth = timelineRect.width; const offsetX = event.clientX - timelineRect.left; - let ratio = offsetX / timelineWidth; ratio = Math.min(Math.max(ratio, 0), 1); - const timelineStartDec = timeToDecimal(startTime.value); const timelineEndDec = timeToDecimal(endTime.value); const startDec = timeToDecimal(getTimeString(resizingQueue.value.startTime)); @@ -492,25 +468,41 @@ function onResizing(event: MouseEvent) { let newTimeDecimal = timelineStartDec + ratio * (timelineEndDec - timelineStartDec); newTimeDecimal = Math.round(newTimeDecimal * 2) / 2; const datePart = getDateString(resizingQueue.value.startTime); - if (resizeDirection.value === 'left') { if (newTimeDecimal >= endDec) return; const newStartStr = datePart + ' ' + decimalToTime(newTimeDecimal); - resizingQueue.value.startTime = newStartStr; + // อัปเดต ghostQueue ให้แสดงผลแบบ real-time + ghostQueue.value.startTime = newStartStr; } else if (resizeDirection.value === 'right') { if (newTimeDecimal <= startDec) return; const newEndStr = datePart + ' ' + decimalToTime(newTimeDecimal); - resizingQueue.value.finishTime = newEndStr; + ghostQueue.value.finishTime = newEndStr; } + // อัปเดต ghostStyle ตาม ghostQueue ใหม่ + const start = getTimeString(ghostQueue.value.startTime); + const end = getTimeString(ghostQueue.value.finishTime); + const startDecimal = timeToDecimal(start); + const endDecimal = timeToDecimal(end); + const totalHours = hours.value.length; + const leftPercent = ((startDecimal - timeToDecimal(startTime.value)) / totalHours) * 100; + const widthPercent = ((endDecimal - startDecimal) / totalHours) * 100; + ghostStyle.left = `${leftPercent}%`; + ghostStyle.width = `${widthPercent}%`; } - -function onResizeEnd() { +async function onResizeEnd() { + if (!resizingQueue.value) return; + console.log(`🔄 Updating Queue ${resizingQueue.value.QueueID} after resize...`); + await queueStore.updateQueue(resizingQueue.value.QueueID, { + startTime: ghostQueue.value.startTime, + finishTime: ghostQueue.value.finishTime + }); resizingQueue.value = null; resizeDirection.value = null; + ghostQueue.value = null; + ghostStyle.display = 'none'; document.removeEventListener('mousemove', onResizing); document.removeEventListener('mouseup', onResizeEnd); } - // Pagination Functions function addPage() { if (pages.value.length < 10) { @@ -520,12 +512,10 @@ function addPage() { alert("Maximum of 10 pages allowed."); } } - function onPageRightClick(page: number, event: MouseEvent) { event.preventDefault(); pageToShowDelete.value = page; } - function deletePage(page: number) { const index = pages.value.indexOf(page); if (index !== -1) { @@ -536,19 +526,15 @@ function deletePage(page: number) { } pageToShowDelete.value = null; } - function onDocumentClick(event: MouseEvent) { const target = event.target as HTMLElement; if (!target.closest('.page-btn')) { pageToShowDelete.value = null; } } - -// Lifecycle Hooks onMounted(() => { document.addEventListener('click', onDocumentClick); }); - onBeforeUnmount(() => { document.removeEventListener('click', onDocumentClick); }); -- GitLab