From 34f7cf069d552095923854f6b80b5a0f1b9d71d1 Mon Sep 17 00:00:00 2001 From: Gemini CLI Date: Sat, 16 May 2026 16:36:52 +0000 Subject: [PATCH] Fix: Umfassendes Refactoring des Print-CSS und Filter-Logik --- src/articles.php | 51 +++++++++++++++++--- src/storage_locations.php | 99 ++++++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 40 deletions(-) diff --git a/src/articles.php b/src/articles.php index a6ceb5c..a8b44ca 100644 --- a/src/articles.php +++ b/src/articles.php @@ -85,7 +85,7 @@ $sql = "SELECT u.username as creator_name, a.household_id, a.product_designation, c.id AS category_id, c.name AS category_name, c.color AS category_color, m.id AS manufacturer_id, m.name AS manufacturer_name, - a.storage_location_id, l2.name AS location_level2_name, l1.name AS location_level1_name + a.storage_location_id, l2.parent_id AS loc_parent_id, l2.name AS location_level2_name, l1.name AS location_level1_name FROM articles a JOIN users u ON a.user_id = u.id LEFT JOIN categories c ON a.category_id = c.id @@ -412,11 +412,32 @@ document.addEventListener('DOMContentLoaded', function () { updateBulkUI(); }); + document.querySelectorAll('.sortable-header').forEach(header => { + header.addEventListener('click', function() { + const sort = this.getAttribute('data-sort'); + if (currentSortColumn === sort) { + currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc'; + } else { + currentSortColumn = sort; + currentSortDirection = 'asc'; + } + // Update icons + document.querySelectorAll('.sortable-header i.fa-sort, .sortable-header i.fa-sort-up, .sortable-header i.fa-sort-down').forEach(icon => { + icon.className = 'fas fa-sort text-muted ms-1'; + }); + const icon = this.querySelector('i'); + icon.className = currentSortDirection === 'asc' ? 'fas fa-sort-up text-primary ms-1' : 'fas fa-sort-down text-primary ms-1'; + + renderTable(); + }); + }); + function renderTable() { const textValue = filterText.value.toLowerCase(); const categoryValue = filterCategory.value; const manufacturerValue = filterManufacturer.value; - const isSearching = textValue.length > 0 || categoryValue || manufacturerValue; + const locationValue = filterLocation ? filterLocation.value : ''; + const isSearching = textValue.length > 0 || categoryValue || manufacturerValue || locationValue; function articleMatchesFilter(article) { const matchesText = article.name.toLowerCase().includes(textValue) || @@ -424,7 +445,10 @@ document.addEventListener('DOMContentLoaded', function () { (article.product_designation && article.product_designation.toLowerCase().includes(textValue)); const matchesCategory = !categoryValue || article.category_id == categoryValue; const matchesManufacturer = !manufacturerValue || article.manufacturer_id == manufacturerValue; - return matchesText && matchesCategory && matchesManufacturer; + const locId = article.storage_location_id; + const locParentId = article.loc_parent_id; + const matchesLocation = !locationValue || locId == locationValue || locParentId == locationValue; + return matchesText && matchesCategory && matchesManufacturer && matchesLocation; } const filteredList = articlesHierarchical.filter(article => { @@ -460,12 +484,23 @@ document.addEventListener('DOMContentLoaded', function () { else cmp = a.localeCompare(b); return currentSortDirection === 'asc' ? cmp : -cmp; }); - // Sort items inside groups by name Object.keys(groupedArticles).forEach(key => { groupedArticles[key].sort((a, b) => a.name.localeCompare(b.name)); }); } else { - groupedArticles['Suchergebnisse'] = [...filteredList]; + // Flatten the list for sorting all items (including children) independent of hierarchy + const flatList = []; + function flatten(list) { + list.forEach(item => { + flatList.push(item); + if (item.children && item.children.length > 0) { + flatten(item.children); + } + }); + } + flatten(filteredList); + + groupedArticles['Suchergebnisse'] = flatList; groupedArticles['Suchergebnisse'].sort((a, b) => { let valA = a[currentSortColumn] || ''; let valB = b[currentSortColumn] || ''; @@ -515,9 +550,9 @@ document.addEventListener('DOMContentLoaded', function () { if (!isCollapsed) { items.forEach(article => { - tableHTML += generateRowHTML(article); + tableHTML += generateRowHTML(article, 0, isGrouped); gridHTML += generateCardHTML(article); - if (article.children.length > 0) { + if (isGrouped && article.children.length > 0) { article.children.forEach(child => { gridHTML += generateCardHTML(child); }); @@ -764,4 +799,6 @@ document.addEventListener('DOMContentLoaded', function () { }); +/script> + \ No newline at end of file diff --git a/src/storage_locations.php b/src/storage_locations.php index 9ccfe49..8bff12f 100644 --- a/src/storage_locations.php +++ b/src/storage_locations.php @@ -322,53 +322,86 @@ function showBarcode(token, name) { new bootstrap.Modal(document.getElementById('barcodeModal')).show(); } -function showAllBarcodes(jsonStr, level1Name) { - const data = JSON.parse(jsonStr); +window.currentBarcodeData = []; +window.currentBarcodeLevel1Name = ''; + +window.showAllBarcodes = function(jsonStr, level1Name) { + window.currentBarcodeData = JSON.parse(jsonStr); + window.currentBarcodeLevel1Name = level1Name; + document.getElementById('printModalLabel').textContent = "QR-Codes für: " + level1Name; + window.renderAllBarcodes(); + new bootstrap.Modal(document.getElementById('printModal')).show(); +} + +window.renderAllBarcodes = function() { const container = document.getElementById('allBarcodesContainer'); container.innerHTML = ''; const baseUrl = window.location.origin + window.location.pathname.replace('storage_locations.php', 'public_location.php?token='); - - document.getElementById('printModalLabel').textContent = "QR-Codes für: " + level1Name; + const sizeMM = document.getElementById('qrSizeInput') ? document.getElementById('qrSizeInput').value : 40; - data.forEach(item => { + window.currentBarcodeData.forEach(item => { const url = baseUrl + item.token; const col = document.createElement('div'); - col.className = 'col-6 col-md-4 mb-4 text-center'; + col.className = 'print-item text-center'; + col.style.cssText = 'margin: 10px; page-break-inside: avoid; display: inline-block; width: ' + (parseInt(sizeMM) + 20) + 'mm;'; col.innerHTML = ` -
+

${item.name}

- QR Code + QR Code
`; container.appendChild(col); }); - - new bootstrap.Modal(document.getElementById('printModal')).show(); -} - -function printDiv(divId) { - var printContents = document.getElementById(divId).innerHTML; - var originalContents = document.body.innerHTML; - document.body.innerHTML = ` - - - `; - - // Wait a brief moment to ensure QR code images from the external API are fully loaded before triggering print - setTimeout(function() { - window.print(); - document.body.innerHTML = originalContents; - window.location.reload(); // Reload to restore event listeners after print - }, 500); } + +