Fix: Artikel-Sortierung, Lagerort-Filter Logik und QR-Code Druckgröße
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 33s

This commit is contained in:
Gemini CLI
2026-05-16 16:20:35 +00:00
parent cc5c16c66d
commit aafc5e95fc
2 changed files with 71 additions and 19 deletions

View File

@@ -226,13 +226,13 @@ $conn->close();
<th style="width: 40px;"><input type="checkbox" id="bulk-select-all" class="form-check-input" title="Alle sichtbaren auswählen"></th>
<th style="width: 60px;">Bild</th>
<th style="width: 40px;"><i class="fas fa-link"></i></th>
<th>Name</th>
<th>Hersteller</th>
<th>Modell/Typ</th>
<th>Gewicht</th>
<th>Anzahl</th>
<th>Kategorie</th>
<th>Lagerort</th>
<th class="sortable-header" data-sort="name" style="cursor:pointer;">Name <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="manufacturer_name" style="cursor:pointer;">Hersteller <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="product_designation" style="cursor:pointer;">Modell/Typ <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="weight_grams" style="cursor:pointer;">Gewicht <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="quantity_owned" style="cursor:pointer;">Anzahl <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="category_name" style="cursor:pointer;">Kategorie <i class="fas fa-sort text-muted ms-1"></i></th>
<th class="sortable-header" data-sort="location_level1_name" style="cursor:pointer;">Lagerort <i class="fas fa-sort text-muted ms-1"></i></th>
<th>Besitzer</th>
<th>Status</th>
<th>Aktionen</th>
@@ -441,18 +441,51 @@ document.addEventListener('DOMContentLoaded', function () {
});
document.getElementById('export_ids_input').value = exportIds.join(',');
const isGrouped = (currentSortColumn === 'category_name');
const groupedArticles = {};
filteredList.forEach(article => {
const catName = article.category_name || 'Ohne Kategorie';
if (!groupedArticles[catName]) groupedArticles[catName] = [];
groupedArticles[catName].push(article);
});
let sortedCategories = [];
const sortedCategories = Object.keys(groupedArticles).sort((a, b) => {
if (a === 'Ohne Kategorie') return 1;
if (b === 'Ohne Kategorie') return -1;
return a.localeCompare(b);
});
if (isGrouped) {
filteredList.forEach(article => {
const catName = article.category_name || 'Ohne Kategorie';
if (!groupedArticles[catName]) groupedArticles[catName] = [];
groupedArticles[catName].push(article);
});
sortedCategories = Object.keys(groupedArticles).sort((a, b) => {
let cmp = 0;
if (a === 'Ohne Kategorie') cmp = 1;
else if (b === 'Ohne Kategorie') cmp = -1;
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];
groupedArticles['Suchergebnisse'].sort((a, b) => {
let valA = a[currentSortColumn] || '';
let valB = b[currentSortColumn] || '';
if (currentSortColumn === 'weight_grams' || currentSortColumn === 'quantity_owned') {
valA = parseFloat(valA) || 0;
valB = parseFloat(valB) || 0;
return currentSortDirection === 'asc' ? valA - valB : valB - valA;
} else if (currentSortColumn === 'location_level1_name') {
valA = (a.location_level1_name || '') + (a.location_level2_name || '');
valB = (b.location_level1_name || '') + (b.location_level2_name || '');
} else {
valA = valA.toString().toLowerCase();
valB = valB.toString().toLowerCase();
}
if (valA < valB) return currentSortDirection === 'asc' ? -1 : 1;
if (valA > valB) return currentSortDirection === 'asc' ? 1 : -1;
return 0;
});
sortedCategories = ['Suchergebnisse'];
}
let tableHTML = '';
let gridHTML = '';

View File

@@ -349,7 +349,15 @@ function showAllBarcodes(jsonStr, level1Name) {
function printDiv(divId) {
var printContents = document.getElementById(divId).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = "<html><head><title>QR-Codes drucken</title></head><body>" + printContents + "</body></html>";
document.body.innerHTML = `
<style>
body { font-family: sans-serif; }
.print-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; }
.print-item { text-align: center; margin-bottom: 20px; page-break-inside: avoid; }
p { margin: 0 0 5px 0; font-size: 14px; font-weight: bold; }
</style>
<div class="print-grid">${printContents}</div>
`;
window.print();
document.body.innerHTML = originalContents;
window.location.reload(); // Reload to restore event listeners after print
@@ -366,7 +374,7 @@ function printDiv(divId) {
<div class="modal-body bg-light">
<div class="mb-4 bg-white p-3 border rounded d-print-none">
<label for="qrSizeInput" class="form-label fw-bold">QR-Code Höhe/Breite (in mm):</label>
<input type="number" id="qrSizeInput" class="form-control" value="40" min="10" max="100" onchange="renderAllBarcodes()">
<input type="number" id="qrSizeInput" class="form-control" value="40" min="10" max="100" oninput="window.renderAllBarcodes()">
</div>
<div class="row" id="allBarcodesContainer"></div>
</div>
@@ -408,3 +416,14 @@ function printDiv(divId) {
</div>
<?php require_once 'footer.php'; ?>
?php require_once 'footer.php'; ?>
<img id="barcodeImage" src="" alt="QR Code" class="img-fluid border p-2 bg-white mb-3" style="max-width: 250px;">
<div class="mt-2">
<a id="barcodeLink" href="" target="_blank" class="btn btn-outline-primary btn-sm"><i class="fas fa-external-link-alt me-2"></i>Link manuell testen</a>
</div>
</div>
</div>
</div>
</div>
<?php require_once 'footer.php'; ?>