feat: Erweiterung der Mindmap-Funktionalität durch Verbesserung der Ladeanimation, Fehlerbehandlung und CSS-Anpassungen; Protokollaktualisierungen zur Fehlerverfolgung und Optimierung der Benutzeroberfläche.

This commit is contained in:
2025-05-16 21:02:09 +01:00
parent 302d5213ef
commit 5b9ae85453
5 changed files with 1028 additions and 532 deletions

View File

@@ -452,7 +452,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape-cose-bilkent/4.1.0/cytoscape-cose-bilkent.min.js"></script>
<!-- Unsere JavaScript-Dateien -->
<script src="{{ url_for('static', filename='js/update_mindmap.js') }}"></script>
<script src="{{ url_for('static', filename='js/update_mindmap.js', v='1.0.1') }}"></script>
<!-- Initialisierung -->
<script>
@@ -483,10 +483,12 @@ document.addEventListener('DOMContentLoaded', function() {
if (cyContainer) {
console.log('Container gefunden:', cyContainer);
// Loader und Statusmeldung anzeigen
loader.style.display = 'block';
statusMessage.textContent = 'Lade Mindmap...';
statusMessage.style.display = 'block';
// Loader und Statusmeldung anzeigen, nur wenn die Elemente existieren
if (loader) loader.style.display = 'block';
if (statusMessage) {
statusMessage.textContent = 'Lade Mindmap...';
statusMessage.style.display = 'block';
}
// Prüfen, ob Cytoscape vorhanden ist
if (typeof cytoscape !== 'undefined') {
@@ -495,14 +497,14 @@ document.addEventListener('DOMContentLoaded', function() {
// Initialisieren der Mindmap
initializeMindmap().then(() => {
// Erfolg: Loader und Statusmeldung ausblenden
loader.style.display = 'none';
statusMessage.style.display = 'none';
if (loader) loader.style.display = 'none';
if (statusMessage) statusMessage.style.display = 'none';
// Event-Listener für Knotenauswahl
window.cy.on('select', 'node', function(event) {
selectedElement = event.target;
editNodeBtn.disabled = false;
deleteElementBtn.disabled = false;
if (editNodeBtn) editNodeBtn.disabled = false;
if (deleteElementBtn) deleteElementBtn.disabled = false;
// Knotendetails im Info-Panel anzeigen
showNodeInfo(selectedElement);
@@ -510,14 +512,14 @@ document.addEventListener('DOMContentLoaded', function() {
window.cy.on('select', 'edge', function(event) {
selectedElement = event.target;
editNodeBtn.disabled = true;
deleteElementBtn.disabled = false;
if (editNodeBtn) editNodeBtn.disabled = true;
if (deleteElementBtn) deleteElementBtn.disabled = false;
});
window.cy.on('unselect', function() {
selectedElement = null;
editNodeBtn.disabled = true;
deleteElementBtn.disabled = true;
if (editNodeBtn) editNodeBtn.disabled = true;
if (deleteElementBtn) deleteElementBtn.disabled = true;
// Info-Panel ausblenden
hideNodeInfo();
@@ -550,124 +552,154 @@ document.addEventListener('DOMContentLoaded', function() {
}).catch(error => {
// Fehler: Fehlermeldung anzeigen
console.error('Mindmap-Initialisierung fehlgeschlagen', error);
loader.style.display = 'none';
statusMessage.textContent = 'Mindmap konnte nicht initialisiert werden: ' + error.message;
statusMessage.style.backgroundColor = 'rgba(220, 38, 38, 0.9)';
statusMessage.style.display = 'block';
if (loader) loader.style.display = 'none';
if (statusMessage) {
statusMessage.textContent = 'Mindmap konnte nicht initialisiert werden: ' + error.message;
statusMessage.style.backgroundColor = 'rgba(220, 38, 38, 0.9)';
statusMessage.style.display = 'block';
}
});
} else {
console.error('Cytoscape ist nicht verfügbar');
loader.style.display = 'none';
statusMessage.textContent = 'Cytoscape-Bibliothek konnte nicht geladen werden';
statusMessage.style.backgroundColor = 'rgba(220, 38, 38, 0.9)';
statusMessage.style.display = 'block';
if (loader) loader.style.display = 'none';
if (statusMessage) {
statusMessage.textContent = 'Cytoscape-Bibliothek konnte nicht geladen werden';
statusMessage.style.backgroundColor = 'rgba(220, 38, 38, 0.9)';
statusMessage.style.display = 'block';
}
}
} else {
console.error('Container #cy nicht gefunden');
}
// Bearbeitungsmodus umschalten
toggleEditModeBtn.addEventListener('click', function() {
isEditMode = !isEditMode;
if (isEditMode) {
// Bearbeitungsmodus aktivieren
crudPanel.style.display = 'flex';
editModeIndicator.classList.add('active');
toggleEditModeBtn.style.display = 'none';
saveChangesBtn.style.display = 'inline-flex';
cancelEditBtn.style.display = 'inline-flex';
window.cy.container().classList.add('editing-mode');
// Bearbeitungsmodus umschalten (nur wenn alle erforderlichen Elemente existieren)
if (toggleEditModeBtn && crudPanel && editModeIndicator && saveChangesBtn && cancelEditBtn && window.cy) {
toggleEditModeBtn.addEventListener('click', function() {
isEditMode = !isEditMode;
// Aktiviere Knotenbewegung (dragging)
window.cy.nodes().unlock();
} else {
// Bearbeitungsmodus deaktivieren
crudPanel.style.display = 'none';
editModeIndicator.classList.remove('active');
toggleEditModeBtn.style.display = 'inline-flex';
saveChangesBtn.style.display = 'none';
cancelEditBtn.style.display = 'none';
window.cy.container().classList.remove('editing-mode');
// Deaktiviere Knotenbewegung
window.cy.nodes().lock();
}
});
if (isEditMode) {
// Bearbeitungsmodus aktivieren
crudPanel.style.display = 'flex';
editModeIndicator.classList.add('active');
toggleEditModeBtn.style.display = 'none';
saveChangesBtn.style.display = 'inline-flex';
cancelEditBtn.style.display = 'inline-flex';
window.cy.container().classList.add('editing-mode');
// Aktiviere Knotenbewegung (dragging)
window.cy.nodes().unlock();
} else {
// Bearbeitungsmodus deaktivieren
crudPanel.style.display = 'none';
editModeIndicator.classList.remove('active');
toggleEditModeBtn.style.display = 'inline-flex';
saveChangesBtn.style.display = 'none';
cancelEditBtn.style.display = 'none';
window.cy.container().classList.remove('editing-mode');
// Deaktiviere Knotenbewegung
window.cy.nodes().lock();
}
});
}
// Änderungen speichern
saveChangesBtn.addEventListener('click', function() {
saveMindmapChanges(window.cy);
});
if (saveChangesBtn && window.cy) {
saveChangesBtn.addEventListener('click', function() {
saveMindmapChanges(window.cy);
});
}
// Bearbeitungsmodus abbrechen
cancelEditBtn.addEventListener('click', function() {
if (confirm('Möchten Sie den Bearbeitungsmodus wirklich verlassen? Nicht gespeicherte Änderungen gehen verloren.')) {
isEditMode = false;
crudPanel.style.display = 'none';
editModeIndicator.classList.remove('active');
toggleEditModeBtn.style.display = 'inline-flex';
saveChangesBtn.style.display = 'none';
cancelEditBtn.style.display = 'none';
window.cy.container().classList.remove('editing-mode');
// Neuinitialisierung der Mindmap
initializeMindmap().then(() => {
loader.style.display = 'none';
statusMessage.style.display = 'none';
});
}
});
if (cancelEditBtn && crudPanel && editModeIndicator && toggleEditModeBtn && saveChangesBtn && loader && statusMessage) {
cancelEditBtn.addEventListener('click', function() {
if (confirm('Möchten Sie den Bearbeitungsmodus wirklich verlassen? Nicht gespeicherte Änderungen gehen verloren.')) {
isEditMode = false;
crudPanel.style.display = 'none';
editModeIndicator.classList.remove('active');
toggleEditModeBtn.style.display = 'inline-flex';
saveChangesBtn.style.display = 'none';
cancelEditBtn.style.display = 'none';
window.cy.container().classList.remove('editing-mode');
// Neuinitialisierung der Mindmap
initializeMindmap().then(() => {
if (loader) loader.style.display = 'none';
if (statusMessage) statusMessage.style.display = 'none';
});
}
});
}
// CRUD-Funktionen
createNodeBtn.addEventListener('click', function() {
if (isEditMode) {
addNewNode(window.cy);
}
});
if (createNodeBtn && window.cy) {
createNodeBtn.addEventListener('click', function() {
if (isEditMode) {
addNewNode(window.cy);
}
});
}
createEdgeBtn.addEventListener('click', function() {
if (isEditMode) {
enableEdgeCreationMode(window.cy);
}
});
if (createEdgeBtn && window.cy) {
createEdgeBtn.addEventListener('click', function() {
if (isEditMode) {
enableEdgeCreationMode(window.cy);
}
});
}
editNodeBtn.addEventListener('click', function() {
if (isEditMode && selectedElement && selectedElement.isNode()) {
editNodeProperties(selectedElement);
}
});
if (editNodeBtn) {
editNodeBtn.addEventListener('click', function() {
if (isEditMode && selectedElement && selectedElement.isNode()) {
editNodeProperties(selectedElement);
}
});
}
deleteElementBtn.addEventListener('click', function() {
if (isEditMode && selectedElement) {
if (selectedElement.isNode()) {
deleteNode(selectedElement);
} else if (selectedElement.isEdge()) {
if (confirm('Möchten Sie diese Verbindung wirklich löschen?')) {
selectedElement.remove();
if (deleteElementBtn) {
deleteElementBtn.addEventListener('click', function() {
if (isEditMode && selectedElement) {
if (selectedElement.isNode()) {
deleteNode(selectedElement);
} else if (selectedElement.isEdge()) {
if (confirm('Möchten Sie diese Verbindung wirklich löschen?')) {
selectedElement.remove();
}
}
}
}
});
});
}
saveMindmapBtn.addEventListener('click', function() {
if (isEditMode) {
saveMindmapChanges(window.cy);
}
});
if (saveMindmapBtn && window.cy) {
saveMindmapBtn.addEventListener('click', function() {
if (isEditMode) {
saveMindmapChanges(window.cy);
}
});
}
// Funktionen für Zoom-Buttons und Reset
document.getElementById('zoomIn').addEventListener('click', function() {
if (window.cy) window.cy.zoom(window.cy.zoom() * 1.2);
});
const zoomInBtn = document.getElementById('zoomIn');
const zoomOutBtn = document.getElementById('zoomOut');
const resetViewBtn = document.getElementById('resetView');
document.getElementById('zoomOut').addEventListener('click', function() {
if (window.cy) window.cy.zoom(window.cy.zoom() * 0.8);
});
if (zoomInBtn && window.cy) {
zoomInBtn.addEventListener('click', function() {
if (window.cy) window.cy.zoom(window.cy.zoom() * 1.2);
});
}
document.getElementById('resetView').addEventListener('click', function() {
if (window.cy) window.cy.fit();
});
if (zoomOutBtn && window.cy) {
zoomOutBtn.addEventListener('click', function() {
if (window.cy) window.cy.zoom(window.cy.zoom() * 0.8);
});
}
if (resetViewBtn && window.cy) {
resetViewBtn.addEventListener('click', function() {
if (window.cy) window.cy.fit();
});
}
});
</script>
{% endblock %}