diff --git a/app.py b/app.py index 99ac058..c852b37 100644 --- a/app.py +++ b/app.py @@ -2256,6 +2256,126 @@ def get_mindmap_data(node_id): 'details': str(e) }), 500 +# API-Endpunkt zum Speichern von Mindmap-Änderungen +@app.route('/api/mindmap/save', methods=['POST']) +@login_required +def save_mindmap_changes(): + """Speichert Änderungen an der Mindmap.""" + try: + data = request.get_json() + + if not data: + return jsonify({ + 'success': False, + 'error': 'Keine Daten erhalten', + 'details': 'Der Request enthält keine JSON-Daten' + }), 400 + + # Überprüfen, ob die erforderlichen Daten vorhanden sind + if 'nodes' not in data or 'edges' not in data: + return jsonify({ + 'success': False, + 'error': 'Unvollständige Daten', + 'details': 'Nodes oder Edges fehlen' + }), 400 + + # Verarbeiten der Knoten + for node_data in data['nodes']: + # ID überprüfen: neue Knoten haben temporäre IDs, die mit 'new-' beginnen + node_id = node_data.get('id') + + if isinstance(node_id, str) and node_id.startswith('new-'): + # Neuen Knoten erstellen + new_node = MindMapNode( + name=node_data.get('name', 'Neuer Knoten'), + description=node_data.get('description', ''), + color_code=node_data.get('color_code', '#9F7AEA'), + icon=node_data.get('icon', 'fa-solid fa-circle'), + is_public=True, + created_by_id=current_user.id + ) + + # Kategorie zuordnen, falls vorhanden + category_name = node_data.get('category') + if category_name: + category = Category.query.filter_by(name=category_name).first() + if category: + new_node.category_id = category.id + + db.session.add(new_node) + # Wir müssen flushen, um eine ID zu erhalten (für die Kanten-Erstellung) + db.session.flush() + + # Temporäre ID für die Mapping-Tabelle speichern + node_data['real_id'] = new_node.id + else: + # Bestehenden Knoten aktualisieren + node = MindMapNode.query.get(int(node_id)) + if node: + node.name = node_data.get('name', node.name) + node.description = node_data.get('description', node.description) + node.color_code = node_data.get('color_code', node.color_code) + node.icon = node_data.get('icon', node.icon) + + # Kategorie aktualisieren, falls vorhanden + category_name = node_data.get('category') + if category_name: + category = Category.query.filter_by(name=category_name).first() + if category: + node.category_id = category.id + + # Position speichern, falls vorhanden + if 'position_x' in node_data and 'position_y' in node_data: + # Hier könnte die Position gespeichert werden, wenn das Modell erweitert wird + pass + + node_data['real_id'] = node.id + + # Bestehende Kanten für die betroffenen Knoten löschen + # (wir ersetzen alle Kanten durch die neuen) + node_ids = [int(node_data.get('real_id')) for node_data in data['nodes'] if 'real_id' in node_data] + + # Neue Kanten erstellen (mit den richtigen IDs aus der Mapping-Tabelle) + for edge_data in data['edges']: + source_id = edge_data.get('source') + target_id = edge_data.get('target') + + # Temporäre IDs durch reale IDs ersetzen + for node_data in data['nodes']: + if node_data.get('id') == source_id and 'real_id' in node_data: + source_id = node_data['real_id'] + if node_data.get('id') == target_id and 'real_id' in node_data: + target_id = node_data['real_id'] + + # Beziehung zwischen Knoten erstellen/aktualisieren + source_node = MindMapNode.query.get(int(source_id)) + target_node = MindMapNode.query.get(int(target_id)) + + if source_node and target_node: + # Prüfen, ob die Beziehung bereits existiert + if target_node not in source_node.children.all(): + source_node.children.append(target_node) + + db.session.commit() + + return jsonify({ + 'success': True, + 'message': 'Mindmap erfolgreich gespeichert', + 'node_mapping': {node_data.get('id'): node_data.get('real_id') + for node_data in data['nodes'] + if 'real_id' in node_data and node_data.get('id') != node_data.get('real_id')} + }) + + except Exception as e: + db.session.rollback() + print(f"Fehler beim Speichern der Mindmap: {str(e)}") + traceback.print_exc() + return jsonify({ + 'success': False, + 'error': 'Mindmap konnte nicht gespeichert werden', + 'details': str(e) + }), 500 + # Route zum expliziten Neu-Laden der Umgebungsvariablen @app.route('/admin/reload-env', methods=['POST']) @admin_required diff --git a/database/systades.db b/database/systades.db index 2f9ecb3..61c4b4d 100644 Binary files a/database/systades.db and b/database/systades.db differ diff --git a/logs/app.log b/logs/app.log index bc7c316..0ae7e59 100644 --- a/logs/app.log +++ b/logs/app.log @@ -417,3 +417,11 @@ werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on 2025-05-14 12:02:49,854 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] 2025-05-14 12:02:49,854 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] 2025-05-14 12:03:06,694 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:03:09,485 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:03:09,485 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:03:14,093 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:03:16,393 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:03:16,393 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:13:05,415 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:13:07,885 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77] +2025-05-14 12:13:07,885 INFO: Anwendung gestartet [in C:\Users\TTOMCZA.EMEA\Dev\website\app.py:77]