From bf71ad79900ddbe3559baf9dda773fb671c9fef5 Mon Sep 17 00:00:00 2001 From: Gemini Agent Date: Tue, 12 May 2026 11:45:27 +0000 Subject: [PATCH] Fix workflow: restore split increments, fix print view, add move modal, adjust Phase 1 card heights - Reverted adjust_single to use UPDATE when an item is already on the table, fixing the first-click bug and preventing duplicate rows in Phase 1. - Added a modal 'Move' button to items in Phase 2 allowing them to be moved between backpacks and compartments directly. - Further reduced the height of Lager cards to remove empty space below buttons. - Fixed the print view by updating the SQL query and adding manufacturer + product designation to the rows. --- src/manage_packing_list_items.php | 97 ++++++++++++++++++++++++++----- src/print_packing_list.php | 10 +++- 2 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/manage_packing_list_items.php b/src/manage_packing_list_items.php index f4dcd38..02ab572 100644 --- a/src/manage_packing_list_items.php +++ b/src/manage_packing_list_items.php @@ -159,17 +159,17 @@ $conn->close(); border: 1px solid #eee; border-radius: 8px; padding: 6px; text-align: center; background: #fff; display: flex; flex-direction: column; transition: transform 0.1s, box-shadow 0.1s; - height: 200px; + height: 165px; } .lager-card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.05); } .lager-img-wrapper { - width: 100%; height: 90px; margin-bottom: 6px; display: flex; + width: 100%; height: 75px; margin-bottom: 4px; display: flex; align-items: center; justify-content: center; overflow: hidden; flex-shrink: 0; } .lager-img-wrapper img.lager-card-img { width: 100% !important; height: 100% !important; - max-width: 100% !important; max-height: 90px !important; + max-width: 100% !important; max-height: 75px !important; object-fit: contain !important; border-radius: 4px; } .lager-title { @@ -178,12 +178,12 @@ $conn->close(); flex-shrink: 0; } .lager-meta { - font-size: 0.7em; color: #6c757d; margin-bottom: 4px; + font-size: 0.7em; color: #6c757d; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.1; flex-shrink: 0; } .lager-controls { - display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: auto; + display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: auto; margin-bottom: 2px; } .table-status-text { font-size: 0.75em; color: #2e7d32; font-weight: 600; @@ -345,6 +345,27 @@ $conn->close(); + +
Änderungen gespeichert!
@@ -566,14 +587,6 @@ $conn->close(); function adjustTable(articleId, delta, includeChildren = false) { sendApiRequest({ action: 'adjust_table_quantity', article_id: articleId, delta: delta, include_children: includeChildren }) - .then(() => { - return fetch('api_packing_list_handler.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ action: 'get_items', packing_list_id: packingListId }) // Fallback to get items - }); - }) - .then(res => res.json()) .then(newItems => { if(Array.isArray(newItems)) packedItems = newItems; // Restore scroll positions @@ -733,7 +746,8 @@ $conn->close(); let metaDisplay = metaDisplayArr.length > 0 ? `(${metaDisplayArr.join(' - ')})` : ''; let controls = ` - + + `; @@ -811,6 +825,8 @@ $conn->close(); }, 300); } + let itemToMoveId = null; + let itemToMoveEl = null; let itemToRemoveId = null; let itemToRemoveEl = null; @@ -821,6 +837,59 @@ $conn->close(); if (!itemEl) return; const itemId = itemEl.dataset.itemId; + if (button.classList.contains('move-item-btn')) { + itemToMoveId = itemId; + itemToMoveEl = itemEl; + + const selectEl = document.getElementById('move-destination-select'); + selectEl.innerHTML = ''; + + // Populate select with all containers + const containers = packedItems.filter(item => item.backpack_id || item.backpack_compartment_id); + // First add backpacks + containers.filter(c => c.backpack_id).forEach(bp => { + const opt = document.createElement('option'); + opt.value = bp.id; + opt.textContent = `👜 Rucksack: ${bp.name}`; + // Get the carrier Name + const carrier = carriers.find(c => String(c.id) === String(bp.carrier_user_id)); + if (carrier) opt.textContent += ` (${carrier.username})`; + selectEl.appendChild(opt); + + // Add its compartments + containers.filter(c => c.parent_packing_list_item_id === bp.id).forEach(comp => { + const optComp = document.createElement('option'); + optComp.value = comp.id; + optComp.textContent = ` ↳ 📁 Fach: ${comp.name}`; + selectEl.appendChild(optComp); + }); + }); + + if (!window.moveItemModalInstance) { + window.moveItemModalInstance = new bootstrap.Modal(document.getElementById('moveItemModal')); + document.getElementById('btn-move-save').onclick = () => { + const destId = document.getElementById('move-destination-select').value; + window.moveItemModalInstance.hide(); + + if (destId === 'table') { + document.getElementById('table-container').appendChild(itemToMoveEl); + } else { + // Find the container element + const destEl = document.querySelector(`.packed-item-container[data-item-id="${destId}"] > .nested-sortable`); + if (destEl) { + destEl.appendChild(itemToMoveEl); + } else { + alert("Fehler: Ziel-Fach nicht in der aktuellen Ansicht gefunden."); + return; + } + } + syncListState(); + }; + } + window.moveItemModalInstance.show(); + return; + } + if (button.classList.contains('remove-item-btn')) { const isTable = (itemEl.closest('#table-container') !== null); if (isTable) { diff --git a/src/print_packing_list.php b/src/print_packing_list.php index a5204e9..b929c97 100644 --- a/src/print_packing_list.php +++ b/src/print_packing_list.php @@ -48,9 +48,11 @@ if ($packing_list) { pli.carrier_user_id, pli.backpack_id, pli.backpack_compartment_id, COALESCE(a.name, pli.name, bp.name, bpc.name, 'Unbekannt') AS name, a.weight_grams, c.name AS category_name, a.consumable, a.image_url, + a.product_designation, m.name AS manufacturer_name, u.username AS carrier_name FROM packing_list_items pli LEFT JOIN articles a ON pli.article_id = a.id + LEFT JOIN manufacturers m ON a.manufacturer_id = m.id LEFT JOIN categories c ON a.category_id = c.id LEFT JOIN backpacks bp ON pli.backpack_id = bp.id LEFT JOIN backpack_compartments bpc ON pli.backpack_compartment_id = bpc.id @@ -129,7 +131,13 @@ function render_rows_recursive($items, $level = 0) { // Name echo ''; if ($level > 0 && !$is_container) echo ''; - echo '' . htmlspecialchars($item['name']) . ''; + + $meta = []; + if (!empty($item['manufacturer_name'])) $meta[] = $item['manufacturer_name']; + if (!empty($item['product_designation'])) $meta[] = $item['product_designation']; + $meta_str = !empty($meta) && !$is_container ? ' (' . htmlspecialchars(implode(' - ', $meta)) . ')' : ''; + + echo '' . htmlspecialchars($item['name']) . '' . $meta_str; echo ''; // Qty