Fix problem with null parent after selecting new graph, add visual showing of active node (for now with heavy solution of re-drawing whole graph)

This commit is contained in:
dimitrievgs 2025-10-14 23:44:53 +03:00
parent 66ce396b48
commit c9f6941cd9
6 changed files with 50 additions and 9 deletions

17
main.js

File diff suppressed because one or more lines are too long

View File

@ -47,6 +47,7 @@ interface BaseNodeWrapperData {
nodeId: string; nodeId: string;
graphId: string; graphId: string;
onNodeDelete: (nodeId: string) => Promise<void>; onNodeDelete: (nodeId: string) => Promise<void>;
isActive: boolean;
app: App; app: App;
} }
@ -312,6 +313,7 @@ interface GraphPanelProps {
onNodeSelectionChange: (nodeId: string, isSelected: boolean) => void; onNodeSelectionChange: (nodeId: string, isSelected: boolean) => void;
onNodeDelete: (nodeId: string) => Promise<void>; onNodeDelete: (nodeId: string) => Promise<void>;
selectedNodeIds: Set<string>; selectedNodeIds: Set<string>;
activeNodeId: string | null;
app: App; app: App;
} }
@ -326,6 +328,7 @@ export const GraphPanelComponent: React.FC<GraphPanelProps> = ({
onNodeSelectionChange, onNodeSelectionChange,
onNodeDelete, onNodeDelete,
selectedNodeIds, selectedNodeIds,
activeNodeId,
app app
}) => { }) => {
// ----------------------------------------------- React Hooks --------------------------------------------------------------- // ----------------------------------------------- React Hooks ---------------------------------------------------------------
@ -351,10 +354,13 @@ export const GraphPanelComponent: React.FC<GraphPanelProps> = ({
graphId: node.graph_id || 'unknown', // пока не передаём id графа с эндпоинтом для экономии трафика - пока так, иначе бы было что-то типо node.data.message.graph_id graphId: node.graph_id || 'unknown', // пока не передаём id графа с эндпоинтом для экономии трафика - пока так, иначе бы было что-то типо node.data.message.graph_id
nodeId: node.id, nodeId: node.id,
app: app, app: app,
is_placeholder: node.data?.is_placeholder || false // НОВОЕ: Передаем статус placeholder is_placeholder: node.data?.is_placeholder || false, // НОВОЕ: Передаем статус placeholder
isActive: node.id === activeNodeId
}, },
position: { x: 0, y: 0 }, position: { x: 0, y: 0 },
className: selectedNodeIds.has(node.id) ? 'selected-node' : '' className: `${selectedNodeIds.has(node.id) ? 'selected-node' : ''} ${
node.id === activeNodeId ? 'active-node' : ''
}`
})); }));
const initialEdgesForLayout = graphData.edges.map((edge) => ({ const initialEdgesForLayout = graphData.edges.map((edge) => ({
@ -379,7 +385,7 @@ export const GraphPanelComponent: React.FC<GraphPanelProps> = ({
setNodes([]); setNodes([]);
setEdges([]); setEdges([]);
} }
}, [graphData.nodes, graphData.edges, onNodeDelete, selectedNodeIds]); // Зависимости: изменения в узлах и рёбрах графа, колбэк удаления, выделенные узлы }, [graphData.nodes, graphData.edges, onNodeDelete, selectedNodeIds, activeNodeId]); // Зависимости: изменения в узлах и рёбрах графа, колбэк удаления, выделенные узлы
// ----------------------------------------------- Event Handlers ------------------------------------------------------------ // ----------------------------------------------- Event Handlers ------------------------------------------------------------
/** /**

View File

@ -834,6 +834,10 @@
height: auto !important; height: auto !important;
} }
.react-flow__node.active-node {
border: 2px solid var(--interactive-accent); /* Красная рамка для активного узла */
box-shadow: 0 0 8px var(--interactive-accent); /* Небольшая тень для выделения */
}
/* Стиль для выделенных узлов */ /* Стиль для выделенных узлов */
.react-flow__node.selected-node { .react-flow__node.selected-node {

View File

@ -109,12 +109,22 @@ export class ChatView extends ItemView {
throw new Error(`Ошибка загрузки сообщений: ${response.status} - ${errorText}`); throw new Error(`Ошибка загрузки сообщений: ${response.status} - ${errorText}`);
} }
const data = await response.json(); const data = await response.json();
// ИСПРАВЛЕНО: Убедиться, что type передается, если это возможно
this.chatHistory = this.chatHistory =
data.map((msg: any) => ({ data.map((msg: any) => ({
...msg, ...msg,
type: msg.type || msg.role // Используем type, если есть, иначе role как fallback type: msg.type || msg.role // Используем type, если есть, иначе role как fallback
})) || []; })) || [];
// Уточнение, чтобы после выбора графа мы создавали узлы с не-пустым родителем
if (this.chatHistory.length > 0) {
// Устанавливаем currentNode на ID последнего сообщения в загруженной истории
this.currentNode = this.chatHistory[this.chatHistory.length - 1].node_id;
} else {
this.currentNode = null; // Если история пуста, current_node_id также null
}
if (this.chatPanel) { if (this.chatPanel) {
await this.chatPanel.updateHistory(this.chatHistory); await this.chatPanel.updateHistory(this.chatHistory);
} }
@ -122,6 +132,12 @@ export class ChatView extends ItemView {
console.error('Ошибка загрузки сообщений:', error); console.error('Ошибка загрузки сообщений:', error);
// Optionally: show a notice to the user // Optionally: show a notice to the user
// new Notice(`Ошибка загрузки сообщений: ${error.message}`); // new Notice(`Ошибка загрузки сообщений: ${error.message}`);
/* Спорно, пока закомментил: this.chatHistory = []; // Очищаем историю при ошибке
this.currentNode = null; // Сбрасываем currentNode при ошибке
if (this.chatPanel) {
await this.chatPanel.updateHistory(this.chatHistory);
}*/
} }
} }

View File

@ -269,6 +269,7 @@ export class GraphView extends ItemView {
onNodeSelectionChange: this.handleNodeSelectionChange.bind(this), // Передаем обработчик изменения выделения onNodeSelectionChange: this.handleNodeSelectionChange.bind(this), // Передаем обработчик изменения выделения
onNodeDelete: this.handleDeleteNode.bind(this), // Передаем колбэк для удаления одиночного узла onNodeDelete: this.handleDeleteNode.bind(this), // Передаем колбэк для удаления одиночного узла
selectedNodeIds: this.selectedNodeIds, // Передаем Set выделенных узлов selectedNodeIds: this.selectedNodeIds, // Передаем Set выделенных узлов
activeNodeId: this.currentNode,
app: this.plugin.app app: this.plugin.app
}) })
); );
@ -406,6 +407,7 @@ export class GraphView extends ItemView {
this.selectedNodeIds.clear(); this.selectedNodeIds.clear();
} }
this.plugin.eventBus.emit('node-selected', { nodeId, graphId: this.selectedGraphId }); this.plugin.eventBus.emit('node-selected', { nodeId, graphId: this.selectedGraphId });
this.renderGraphPanel(); // Временное "жирное" решение с полной перерисовкой графа при каждом выборе узла
} }
/** /**

File diff suppressed because one or more lines are too long