WP19 #10
|
|
@ -9,16 +9,22 @@ from ui_utils import parse_markdown_draft, build_markdown_doc, load_history_from
|
|||
from ui_api import save_draft_to_vault, analyze_draft_text, send_chat_message, submit_feedback
|
||||
from ui_config import HISTORY_FILE, COLLECTION_PREFIX, GRAPH_COLORS
|
||||
|
||||
# --- Helper zum Modus-Wechsel ---
|
||||
def switch_to_editor(note_payload):
|
||||
"""Lädt eine Note in den Editor und wechselt den Tab."""
|
||||
# Wir simulieren eine Message, wie sie der Chatbot zurückgeben würde
|
||||
# --- CALLBACKS ---
|
||||
# Diese müssen oben definiert sein, damit sie VOR dem Re-Run bekannt sind.
|
||||
|
||||
def switch_to_editor_callback(note_payload):
|
||||
"""
|
||||
Callback-Funktion: Wird ausgeführt, wenn der 'Bearbeiten'-Button geklickt wird.
|
||||
Da dies ein Callback ist, können wir session_state Werte ändern, bevor die UI neu gezeichnet wird.
|
||||
"""
|
||||
# 1. Inhalt vorbereiten
|
||||
content = note_payload.get('fulltext', '')
|
||||
if not content:
|
||||
# Fallback: Wir rekonstruieren minimales Markdown
|
||||
# Fallback: Markdown aus Metadaten rekonstruieren, falls kein Fulltext da ist
|
||||
content = build_markdown_doc(note_payload, "Inhalt konnte nicht geladen werden (nur Metadaten verfügbar).")
|
||||
|
||||
# State setzen für den Editor
|
||||
# 2. Nachricht simulieren (als ob der Chatbot sie generiert hätte)
|
||||
# Dies füllt den Editor mit dem Inhalt der Notiz
|
||||
st.session_state.messages.append({
|
||||
"role": "assistant",
|
||||
"intent": "INTERVIEW",
|
||||
|
|
@ -26,16 +32,19 @@ def switch_to_editor(note_payload):
|
|||
"query_id": f"edit_{note_payload['note_id']}"
|
||||
})
|
||||
|
||||
# Modus umschalten (muss via session_state key im Radio-Widget passieren)
|
||||
# 3. Modus umschalten
|
||||
# Das ist der entscheidende Fix: Wir ändern den Wert des Radio-Buttons im State direkt.
|
||||
st.session_state["sidebar_mode_selection"] = "📝 Manueller Editor"
|
||||
st.rerun()
|
||||
|
||||
# --- UI RENDERER ---
|
||||
|
||||
def render_sidebar():
|
||||
with st.sidebar:
|
||||
st.title("🧠 mindnet")
|
||||
st.caption("v2.6 | WP-19 Graph View")
|
||||
|
||||
# State-gebundenes Radio Widget für Modus-Wechsel
|
||||
# State-gebundenes Radio Widget
|
||||
# Wir nutzen 'sidebar_mode_selection' als Key, damit wir ihn programmgesteuert (Callback) ändern können.
|
||||
if "sidebar_mode_selection" not in st.session_state:
|
||||
st.session_state["sidebar_mode_selection"] = "💬 Chat"
|
||||
|
||||
|
|
@ -60,7 +69,7 @@ def render_sidebar():
|
|||
|
||||
def render_draft_editor(msg):
|
||||
"""
|
||||
Rendert den Editor für Drafts (genutzt im Chat bei INTERVIEW Intent oder im manuellen Modus).
|
||||
Der Editor-Kern. Wird sowohl im Chat (Interview-Modus) als auch im manuellen Modus verwendet.
|
||||
"""
|
||||
if "query_id" not in msg or not msg["query_id"]:
|
||||
msg["query_id"] = str(uuid.uuid4())
|
||||
|
|
@ -296,18 +305,18 @@ def render_manual_editor():
|
|||
}
|
||||
render_draft_editor(mock_msg)
|
||||
|
||||
# --- GRAPH EXPLORER (WP-19) ---
|
||||
# --- GRAPH EXPLORER ---
|
||||
|
||||
def render_graph_explorer(graph_service):
|
||||
st.header("🕸️ Graph Explorer")
|
||||
|
||||
# State Init für den Graph-Explorer
|
||||
# State Init
|
||||
if "graph_center_id" not in st.session_state: st.session_state.graph_center_id = None
|
||||
|
||||
# Defaults speichern für Persistenz während der Session (mit setdefault)
|
||||
# Defaults speichern für Persistenz während der Session
|
||||
st.session_state.setdefault("graph_depth", 2)
|
||||
st.session_state.setdefault("graph_show_labels", True)
|
||||
st.session_state.setdefault("graph_spacing", 200) # Standard etwas höher für mehr Luft
|
||||
st.session_state.setdefault("graph_spacing", 200)
|
||||
st.session_state.setdefault("graph_gravity", -3000)
|
||||
|
||||
col_ctrl, col_graph = st.columns([1, 4])
|
||||
|
|
@ -358,20 +367,21 @@ def render_graph_explorer(graph_service):
|
|||
center_id = st.session_state.graph_center_id
|
||||
|
||||
if center_id:
|
||||
# 1. Action Bar für die aktive Node
|
||||
# Action Bar
|
||||
c_action1, c_action2 = st.columns([3, 1])
|
||||
with c_action1:
|
||||
st.caption(f"Aktives Zentrum: **{center_id}**")
|
||||
with c_action2:
|
||||
# Button um die aktuelle Zentrale Note zu editieren
|
||||
if st.button("📝 Bearbeiten", use_container_width=True):
|
||||
note_data = graph_service._fetch_note_cached(center_id)
|
||||
if note_data:
|
||||
switch_to_editor(note_data)
|
||||
else:
|
||||
st.error("Fehler beim Laden der Daten.")
|
||||
# FIX: Button mit Callback (on_click)
|
||||
note_data = graph_service._fetch_note_cached(center_id)
|
||||
if note_data:
|
||||
st.button("📝 Bearbeiten",
|
||||
use_container_width=True,
|
||||
on_click=switch_to_editor_callback,
|
||||
args=(note_data,))
|
||||
else:
|
||||
st.error("Datenfehler")
|
||||
|
||||
# 2. Graph Rendern
|
||||
with st.spinner(f"Lade Graph..."):
|
||||
nodes, edges = graph_service.get_ego_graph(
|
||||
center_id,
|
||||
|
|
@ -382,6 +392,9 @@ def render_graph_explorer(graph_service):
|
|||
if not nodes:
|
||||
st.warning("Keine Daten gefunden. (Notiz existiert evtl. nicht mehr)")
|
||||
else:
|
||||
# FIX: Dynamischer Key erzwingt Neu-Rendern bei Physics-Änderung
|
||||
graph_key = f"graph_{center_id}_{st.session_state.graph_gravity}_{st.session_state.graph_spacing}"
|
||||
|
||||
config = Config(
|
||||
width=1000,
|
||||
height=800,
|
||||
|
|
@ -395,26 +408,23 @@ def render_graph_explorer(graph_service):
|
|||
solver="forceAtlas2Based",
|
||||
forceAtlas2Based={
|
||||
"theta": 0.5,
|
||||
"gravitationalConstant": st.session_state.graph_gravity, # Dynamisch
|
||||
"gravitationalConstant": st.session_state.graph_gravity,
|
||||
"centralGravity": 0.005,
|
||||
"springConstant": 0.08,
|
||||
"springLength": st.session_state.graph_spacing, # Dynamisch
|
||||
"springLength": st.session_state.graph_spacing,
|
||||
"damping": 0.4,
|
||||
"avoidOverlap": 1
|
||||
},
|
||||
stabilization={"enabled": True, "iterations": 800}
|
||||
)
|
||||
|
||||
# Interaktion
|
||||
return_value = agraph(nodes=nodes, edges=edges, config=config)
|
||||
return_value = agraph(nodes=nodes, edges=edges, config=config, key=graph_key)
|
||||
|
||||
if return_value:
|
||||
# Wenn auf eine andere Node geklickt wurde:
|
||||
if return_value != center_id:
|
||||
st.session_state.graph_center_id = return_value
|
||||
st.rerun()
|
||||
else:
|
||||
# Wenn auf die ZENTRALE Node geklickt wurde
|
||||
st.toast(f"Zentrum: {return_value}")
|
||||
|
||||
else:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user