import React, { useState, useEffect } from "react"; import ChatPanel from "./components/ChatPanel"; import GraphPanel from "./components/GraphPanel"; import HistoryPanel from "./components/HistoryPanel"; import "./App.css"; function App() { const [graphData, setGraphData] = useState({ nodes: [], edges: [] }); const [chatHistory, setChatHistory] = useState([]); const [currentNode, setCurrentNode] = useState(null); const [graphsList, setGraphsList] = useState([]); const [selectedGraphId, setSelectedGraphId] = useState(null); const API_BASE_URL = "http://localhost:5000/api"; // Укажи базовый URL для API useEffect(() => { fetchGraphsList(); if (selectedGraphId) { fetchGraphData(selectedGraphId); } }, [selectedGraphId]); const fetchGraphsList = async () => { try { const response = await fetch(`${API_BASE_URL}/graphs`); // Используй базовый URL const data = await response.json(); setGraphsList(data); } catch (error) { console.error("Error fetching graphs:", error); } }; const fetchGraphData = async (graphId) => { try { const response = await fetch(`${API_BASE_URL}/graphs/${graphId}`); // Используй базовый URL if (!response.ok) { // Если статус ответа не 200-299, выбрасываем ошибку if (response.status === 404) { console.error(`Graph with id ${graphId} not found.`); // Здесь можно добавить логику для отображения сообщения пользователю // Например, установить состояние ошибки и отобразить сообщение в UI // setErrorMessage(`Graph with id ${graphId} not found.`); } throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log("Fetched graph data:", data); // Добавлено для отладки setGraphData({ nodes: data.graph_nodes.map((node) => ({ id: node.id, data: { label: node.data.label }, })), edges: data.graph_edges.map((edge) => ({ id: edge.id, source: edge.source, target: edge.target, })), }); setChatHistory(data.messages); } catch (error) { console.error("Error fetching graph data:", error); } }; const handleSendMessage = async (message) => { try { const response = await fetch(`${API_BASE_URL}/chat`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ message: message, graph_id: selectedGraphId, parent_node_id: currentNode, }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); console.log("Result from API:", result); setGraphData({ nodes: result.graph_visualization_data.nodes.map((node) => ({ id: node.id, data: { label: node.data.label }, })), edges: result.graph_visualization_data.edges.map((edge) => ({ id: edge.id, source: edge.source, target: edge.target, })), }); // Обновляем выбранный ID графа setSelectedGraphId(result.graph_id); // Устанавливаем текущий узел на тот, который был последним в ответе агента const newCurrentNodeId = result.graph_visualization_data.current_node_id; setCurrentNode(newCurrentNodeId); // Всегда загружаем сообщения от корня до нового текущего узла // Это гарантирует, что в чате отображается только текущая ветка if (newCurrentNodeId) { await fetchMessagesFromRootToNode(newCurrentNodeId); } else { // Если почему-то current_node_id не пришел (что не должно быть при успешном ответе), // используем полную историю, хотя это менее предпочтительно. setChatHistory(result.messages); } } catch (error) { console.error("Error sending message:", error); } }; // Новая функция для получения сообщений от корня до выбранной ноды const fetchMessagesFromRootToNode = async (nodeId) => { try { const response = await fetch(`${API_BASE_URL}/messages/${selectedGraphId}/${nodeId}`); // Используй базовый URL const data = await response.json(); setChatHistory(data); // Обновляем историю чата только сообщениями от корня до выбранной ноды } catch (error) { console.error("Error fetching messages:", error); } }; const handleNodeClick = (nodeId) => { setCurrentNode(nodeId); fetchMessagesFromRootToNode(nodeId); // Получаем сообщения при клике на ноду }; const handleGraphSelect = (graphId) => { setSelectedGraphId(graphId); }; // Новая функция для создания нового чата const handleNewChat = () => { setGraphData({ nodes: [], edges: [] }); // Очищаем данные графа setChatHistory([]); // Очищаем историю чата setCurrentNode(null); // Сбрасываем текущий выбранный узел setSelectedGraphId(null); // Сбрасываем выбранный ID графа (чтобы бэкенд создал новый) }; return (