166 lines
6.1 KiB
JavaScript
166 lines
6.1 KiB
JavaScript
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 (
|
|
<div className="app-container">
|
|
{/* Передаем handleNewChat в HistoryPanel */}
|
|
<HistoryPanel
|
|
graphs={graphsList}
|
|
onGraphSelect={handleGraphSelect}
|
|
onNewChat={handleNewChat}
|
|
/>
|
|
<GraphPanel graphData={graphData} onNodeClick={handleNodeClick} />
|
|
<ChatPanel chatHistory={chatHistory} onSendMessage={handleSendMessage} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default App;
|