function cephCalculator() { return { replicationType: 'replication', replicas: 3, minSize: 2, k: 4, m: 2, storageUnit: 'TB', nodes: [ { osd_count: 4, osd_size_gb: 1000 } ], result: { max_usage_percent: 0, max_usage_gb: 0, max_usage_tb: 0, raw_total: 0 }, isCalculating: false, init() { const savedConfig = localStorage.getItem('lastConfig'); if (savedConfig) { const config = JSON.parse(savedConfig); Object.assign(this, config); } }, addNode() { this.nodes.push({ osd_count: 4, osd_size_gb: this.storageUnit === 'TB' ? 1000 : 1 }); }, removeNode(nodeIndex) { this.nodes.splice(nodeIndex, 1); if (this.nodes.length === 0) { this.addNode(); } }, getOsdSizeInGB(size) { return this.storageUnit === 'TB' ? size * 1024 : size; }, calculateCapacity() { const data = { replication_type: this.replicationType, replicas: parseInt(this.replicas), k: parseInt(this.k), m: parseInt(this.m), nodes: this.nodes.map(node => ({ osd_count: parseInt(node.osd_count), osd_size_gb: this.getOsdSizeInGB(parseFloat(node.osd_size_gb)) })), min_size: parseInt(this.minSize), storage_unit: this.storageUnit }; this.isCalculating = true; fetch('/calculate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') }, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => { this.result = data; }) .catch(error => { console.error('Fehler bei der Berechnung:', error); alert('Es ist ein Fehler bei der Berechnung aufgetreten. Bitte versuchen Sie es erneut.'); }) .finally(() => { this.isCalculating = false; }); }, exportConfig() { const config = { replicationType: this.replicationType, replicas: this.replicas, minSize: this.minSize, k: this.k, m: this.m, storageUnit: this.storageUnit, nodes: this.nodes, result: this.result }; const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'ceph-config.json'; a.click(); URL.revokeObjectURL(url); }, importConfig(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const config = JSON.parse(e.target.result); Object.assign(this, config); // Berechne automatisch nach dem Import this.calculateCapacity(); } catch (error) { alert('Fehler beim Importieren der Konfiguration. Bitte überprüfen Sie das Dateiformat.'); } }; reader.readAsText(file); }, generatePDF() { if (!this.result.raw_total) { alert('Bitte führen Sie zuerst eine Berechnung durch.'); return; } // Validiere die Daten vor dem Senden if (!this.nodes || this.nodes.length === 0) { alert('Bitte fügen Sie mindestens einen Node hinzu.'); return; } // Validiere die Node-Daten for (let i = 0; i < this.nodes.length; i++) { const node = this.nodes[i]; if (!node.osd_count || node.osd_count < 1) { alert(`Bitte geben Sie eine gültige Anzahl von OSDs für Node ${i + 1} ein.`); return; } if (!node.osd_size_gb || node.osd_size_gb <= 0) { alert(`Bitte geben Sie eine gültige OSD-Größe für Node ${i + 1} ein.`); return; } } const data = { replication_type: this.replicationType, replicas: parseInt(this.replicas), min_size: parseInt(this.minSize), k: parseInt(this.k), m: parseInt(this.m), storage_unit: this.storageUnit, nodes: this.nodes.map(node => ({ osd_count: parseInt(node.osd_count), osd_size_gb: parseFloat(this.getOsdSizeInGB(parseFloat(node.osd_size_gb))) })), result: { raw_total: parseFloat(this.result.raw_total), max_usage_percent: parseFloat(this.result.max_usage_percent), max_usage_gb: parseFloat(this.result.max_usage_gb), max_usage_tb: parseFloat(this.result.max_usage_tb), node_failure_tolerance: Boolean(this.result.node_failure_tolerance), node_failure_info: String(this.result.node_failure_info || ''), multi_failure_tolerance: Boolean(this.result.multi_failure_tolerance), max_failure_nodes: parseInt(this.result.max_failure_nodes || 0), osd_failure_tolerance: Boolean(this.result.osd_failure_tolerance), osd_failure_info: String(this.result.osd_failure_info || '') } }; // Zeige Ladeindikator const button = document.querySelector('button[onclick="generatePDF()"]'); const originalText = button.innerHTML; button.innerHTML = 'Generiere PDF...'; button.disabled = true; // Hole CSRF-Token const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); if (!csrfToken) { alert('CSRF-Token nicht gefunden. Bitte laden Sie die Seite neu.'); button.innerHTML = originalText; button.disabled = false; return; } fetch('/generate-pdf', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken }, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { return response.json().then(err => { throw new Error(err.error || `HTTP error! status: ${response.status}`); }); } return response.blob(); }) .then(blob => { if (!blob || blob.size === 0) { throw new Error('Die generierte PDF-Datei ist leer'); } const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'ceph-report.pdf'; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); }) .catch(error => { console.error('Fehler bei der PDF-Generierung:', error); alert(`Fehler bei der PDF-Generierung: ${error.message}`); }) .finally(() => { // Stelle den Button wieder her button.innerHTML = originalText; button.disabled = false; }); } }; }