From fe2d758676e8dc0551d2e8a748b76538aa4f2195 Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Sat, 1 Nov 2025 11:58:45 +0100 Subject: [PATCH 1/2] Added drag-and-drop functionality --- src/Views/Shared/_Batch.cshtml | 135 ++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/src/Views/Shared/_Batch.cshtml b/src/Views/Shared/_Batch.cshtml index b3a2642..ad40cbc 100644 --- a/src/Views/Shared/_Batch.cshtml +++ b/src/Views/Shared/_Batch.cshtml @@ -83,7 +83,7 @@ } else { assetCard.innerHTML = `
-
Asset ${i}: @T["Empty"]
+
Asset ${i + 1}: @T["Empty"]
@@ -148,6 +148,7 @@ modalBody.appendChild(errorDiv); } } + enableDragAndDrop(); }); async function renderBarcodePreview(containerId = "printPreviewContainer") { @@ -174,6 +175,7 @@ const cell = document.createElement("div"); cell.className = "barcode-cell border rounded p-1 d-flex flex-column align-items-center justify-content-center"; cell.style.minHeight = "120px"; + cell.setAttribute("data-id", i); var isMobileM = window.innerWidth < 992 && window.innerWidth >= 576; var isMobileS = window.innerWidth < 576; @@ -216,15 +218,20 @@ grid.appendChild(cell); } } + enableBarcodeDragAndDrop(); } function moveCardInBatch(index, direction) { + const newIndex = direction === 'up' ? index - 1 : index - 0 + 1; + swapCardsInBatch(index, newIndex); + } + + function swapCardsInBatch(index, newIndex) { let batch = getAssetIdsFromBatch(); padNulls(batch, 24); if (!batch || batch.length === 0) return; - const newIndex = direction === 'up' ? index - 1 : index - 0 + 1; // Prevent out-of-bounds movement if (newIndex < 0 || newIndex >= batch.length) return; @@ -244,7 +251,131 @@ localStorage.setItem("printBatch", JSON.stringify(batch)); renderBarcodePreview(); } + + function enableDragAndDrop() { + const cards = document.querySelectorAll('#printModal .card'); + const modalBody = document.querySelector('#printModal .modal-body'); + let draggedCard = null; + cards.forEach(card => { + card.setAttribute('draggable', 'true'); + + card.addEventListener('dragstart', e => { + draggedCard = card; + e.dataTransfer.effectAllowed = 'move'; + e.target.style.opacity = '0.5'; + }); + + card.addEventListener('dragend', e => { + e.target.style.opacity = '1'; + draggedCard = null; + updateBatchOrderFromDOM(); + }); + + card.addEventListener('dragover', e => { + e.preventDefault(); + e.dataTransfer.dropEffect = 'move'; + const bounding = card.getBoundingClientRect(); + const offset = bounding.y + (bounding.height / 2); + if (e.clientY - offset > 0) { + card.style['border-bottom'] = '2px solid #007bff'; + card.style['border-top'] = ''; + } else { + card.style['border-top'] = '2px solid #007bff'; + card.style['border-bottom'] = ''; + } + }); + + card.addEventListener('dragleave', e => { + card.style['border-bottom'] = ''; + card.style['border-top'] = ''; + }); + + card.addEventListener('drop', e => { + e.preventDefault(); + card.style['border-bottom'] = ''; + card.style['border-top'] = ''; + const bounding = card.getBoundingClientRect(); + const offset = bounding.y + (bounding.height / 2); + if (e.clientY - offset > 0) { + card.after(draggedCard); + } else { + card.before(draggedCard); + } + updateBatchOrderFromDOM(); + }); + }); + } + + function updateBatchOrderFromDOM() { + const newOrder = []; + const cards = document.querySelectorAll('#printModal .card'); + + cards.forEach((card, index) => { + // Update index attribute + card.setAttribute('data-card-index', index); + + // Update the title text + const title = card.querySelector('.card-title strong'); + if (title) title.textContent = `Asset ${index + 1}:`; + + // Get asset CN if available + const assetCn = card.querySelector('.card-body')?.getAttribute('data-cn'); + newOrder.push(assetCn || null); + }); + + localStorage.setItem("printBatch", JSON.stringify(newOrder)); + renderBarcodePreview("printPreviewContainer"); + } + + function enableBarcodeDragAndDrop() { + const cells = document.querySelectorAll('#printPreviewContainer .barcode-cell'); + const container = document.querySelector('#printPreviewContainer .barcode-grid'); + let draggedCell = null; + + cells.forEach(cell => { + cell.setAttribute('draggable', 'true'); + + cell.addEventListener('dragstart', e => { + draggedCell = cell; + e.dataTransfer.effectAllowed = 'move'; + cell.style.opacity = '0.5'; + }); + + cell.addEventListener('dragend', e => { + cell.style.opacity = '1'; + draggedCell = null; + }); + + cell.addEventListener('dragover', e => { + e.preventDefault(); + const bounding = cell.getBoundingClientRect(); + const offset = bounding.y + bounding.height / 2; + if (e.clientY - offset > 0) { + cell.style['border-bottom'] = '2px solid #007bff'; + cell.style['border-top'] = ''; + } else { + cell.style['border-top'] = '2px solid #007bff'; + cell.style['border-bottom'] = ''; + } + }); + + cell.addEventListener('dragleave', e => { + cell.style['border-bottom'] = ''; + cell.style['border-top'] = ''; + }); + + cell.addEventListener('drop', e => { + e.preventDefault(); + cell.style['border-bottom'] = ''; + cell.style['border-top'] = ''; + cell.after(draggedCell); + let index = cell.getAttribute("data-id"); + let newIndex = draggedCell.getAttribute("data-id"); + swapCardsInBatch(index, newIndex); + }); + }); + } function getAssetIdsFromBatch() { let currentData = JSON.parse(localStorage.getItem("printBatch")); From 66a5a976ec3e3452c30cfa222259651314fe023e Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Sat, 1 Nov 2025 13:15:30 +0100 Subject: [PATCH 2/2] Fixed barcode timing issue in print preview --- src/Views/Shared/_Batch.cshtml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Views/Shared/_Batch.cshtml b/src/Views/Shared/_Batch.cshtml index ad40cbc..3e46da9 100644 --- a/src/Views/Shared/_Batch.cshtml +++ b/src/Views/Shared/_Batch.cshtml @@ -490,10 +490,16 @@
-