// Globale Variablen let spoolmanUrl = ''; let spoolsData = []; // Hilfsfunktionen für Datenmanipulation function processSpoolData(data) { return data.map(spool => ({ id: spool.id, remaining_weight: spool.remaining_weight, remaining_length: spool.remaining_length, filament: spool.filament, extra: spool.extra })); } // Dropdown-Funktionen function populateVendorDropdown(data, selectedSmId = null) { const vendorSelect = document.getElementById("vendorSelect"); if (!vendorSelect) { console.error('vendorSelect Element nicht gefunden'); return; } const onlyWithoutSmId = document.getElementById("onlyWithoutSmId"); if (!onlyWithoutSmId) { console.error('onlyWithoutSmId Element nicht gefunden'); return; } // Separate Objekte für alle Hersteller und gefilterte Hersteller const allVendors = {}; const filteredVendors = {}; vendorSelect.innerHTML = ''; let vendorIdToSelect = null; let totalSpools = 0; let spoolsWithoutTag = 0; let totalWeight = 0; let totalLength = 0; // Neues Objekt für Material-Gruppierung const materials = {}; data.forEach(spool => { if (!spool.filament || !spool.filament.vendor) { return; } totalSpools++; // Material zählen und gruppieren if (spool.filament.material) { const material = spool.filament.material.toUpperCase(); // Normalisierung materials[material] = (materials[material] || 0) + 1; } // Addiere Gewicht und Länge if (spool.remaining_weight) { totalWeight += spool.remaining_weight; } if (spool.remaining_length) { totalLength += spool.remaining_length; } const vendor = spool.filament.vendor; const hasValidNfcId = spool.extra && spool.extra.nfc_id && spool.extra.nfc_id !== '""' && spool.extra.nfc_id !== '"\\"\\"\\""'; if (!hasValidNfcId) { spoolsWithoutTag++; } // Alle Hersteller sammeln if (!allVendors[vendor.id]) { allVendors[vendor.id] = vendor.name; } // Gefilterte Hersteller für Dropdown if (!filteredVendors[vendor.id]) { if (!onlyWithoutSmId.checked || !hasValidNfcId) { filteredVendors[vendor.id] = vendor.name; } } }); // Nach der Schleife: Formatierung der Gesamtlänge const lengthInM = totalLength / 1000; // erst in m umrechnen const formattedLength = lengthInM > 1000 ? (lengthInM / 1000).toFixed(2) + " km" : lengthInM.toFixed(2) + " m"; // Formatierung des Gesamtgewichts (von g zu kg zu t) const weightInKg = totalWeight / 1000; // erst in kg umrechnen const formattedWeight = weightInKg > 1000 ? (weightInKg / 1000).toFixed(2) + " t" : weightInKg.toFixed(2) + " kg"; // Dropdown mit gefilterten Herstellern befüllen - alphabetisch sortiert Object.entries(filteredVendors) .sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) // Sort vendors alphabetically by name .forEach(([id, name]) => { const option = document.createElement("option"); option.value = id; option.textContent = name; vendorSelect.appendChild(option); }); document.getElementById("totalSpools").textContent = totalSpools; document.getElementById("spoolsWithoutTag").textContent = spoolsWithoutTag; // Zeige die Gesamtzahl aller Hersteller an document.getElementById("totalVendors").textContent = Object.keys(allVendors).length; // Neue Statistiken hinzufügen document.getElementById("totalWeight").textContent = formattedWeight; document.getElementById("totalLength").textContent = formattedLength; // Material-Statistiken zum DOM hinzufügen const materialsList = document.getElementById("materialsList"); materialsList.innerHTML = ''; Object.entries(materials) .sort(([,a], [,b]) => b - a) // Sortiere nach Anzahl absteigend .forEach(([material, count]) => { const li = document.createElement("li"); li.textContent = `${material}: ${count} ${count === 1 ? 'Spool' : 'Spools'}`; materialsList.appendChild(li); }); if (vendorIdToSelect) { vendorSelect.value = vendorIdToSelect; updateFilamentDropdown(selectedSmId); } } function updateFilamentDropdown(selectedSmId = null) { const vendorId = document.getElementById("vendorSelect").value; const dropdownContentInner = document.getElementById("filament-dropdown-content"); const filamentSection = document.getElementById("filamentSection"); const onlyWithoutSmId = document.getElementById("onlyWithoutSmId").checked; const selectedText = document.getElementById("selected-filament"); const selectedColor = document.getElementById("selected-color"); dropdownContentInner.innerHTML = ''; selectedText.textContent = "Bitte wählen..."; selectedColor.style.backgroundColor = '#FFFFFF'; if (vendorId) { const filteredFilaments = spoolsData.filter(spool => { if (!spool?.filament?.vendor?.id) { console.log('Problem aufgetreten bei: ', spool?.filament?.vendor); console.log('Problematische Spulen:', spoolsData.filter(spool => !spool?.filament?.vendor?.id)); return false; } const hasValidNfcId = spool.extra && spool.extra.nfc_id && spool.extra.nfc_id !== '""' && spool.extra.nfc_id !== '"\\"\\"\\""'; return spool.filament.vendor.id == vendorId && (!onlyWithoutSmId || !hasValidNfcId); }); filteredFilaments.forEach(spool => { const option = document.createElement("div"); option.className = "dropdown-option"; option.setAttribute("data-value", spool.filament.id); option.setAttribute("data-nfc-id", spool.extra.nfc_id || ""); // Generate color representation based on filament type (single or multi color) let colorHTML = ''; // Check if this is a multicolor filament if (spool.filament.multi_color_hexes) { // Parse multi color hexes from comma-separated string const colors = spool.filament.multi_color_hexes.replace(/#/g, '').split(','); // Determine the display style based on direction const direction = spool.filament.multi_color_direction || 'coaxial'; // Generate color circles for each color colorHTML = '