Buf fix (emit new chat also for ChatView)
This commit is contained in:
parent
04a19b2508
commit
dfe27f79ef
|
|
@ -30,17 +30,15 @@ import { Handle, Position } from 'reactflow';
|
||||||
// Простой компонент для узла типа 'user'
|
// Простой компонент для узла типа 'user'
|
||||||
// Это базовый пример. Ты можешь стилизовать его по своему усмотрению.
|
// Это базовый пример. Ты можешь стилизовать его по своему усмотрению.
|
||||||
const UserNode: React.FC<any> = ({ data, isConnectable }) => {
|
const UserNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
return React.createElement('div', {
|
return React.createElement(React.Fragment, null, // Используем React.Fragment для возврата нескольких элементов без лишнего div
|
||||||
className: 'react-flow__node-user'
|
|
||||||
},
|
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "source",
|
type: "source",
|
||||||
position: Position.Bottom,
|
position: Position.Bottom,
|
||||||
isConnectable: isConnectable,
|
isConnectable: isConnectable,
|
||||||
}),
|
}),
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "target",
|
type: "target",
|
||||||
position: Position.Top,
|
position: Position.Top,
|
||||||
isConnectable: isConnectable,
|
isConnectable: isConnectable,
|
||||||
}),
|
}),
|
||||||
data.label
|
data.label
|
||||||
|
|
@ -49,9 +47,7 @@ const UserNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
|
|
||||||
// Простой компонент для узла типа 'llm'
|
// Простой компонент для узла типа 'llm'
|
||||||
const LLMNode: React.FC<any> = ({ data, isConnectable }) => {
|
const LLMNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
return React.createElement('div', {
|
return React.createElement(React.Fragment, null,
|
||||||
className: 'react-flow__node-llm'
|
|
||||||
},
|
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "source",
|
type: "source",
|
||||||
position: Position.Bottom,
|
position: Position.Bottom,
|
||||||
|
|
@ -68,15 +64,13 @@ const LLMNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
|
|
||||||
// Простой компонент для узла типа 'tool'
|
// Простой компонент для узла типа 'tool'
|
||||||
const ToolNode: React.FC<any> = ({ data, isConnectable }) => {
|
const ToolNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
return React.createElement('div', {
|
return React.createElement(React.Fragment, null,
|
||||||
className: 'react-flow__node-tool'
|
|
||||||
},
|
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "source",
|
type: "source",
|
||||||
position: Position.Bottom,
|
position: Position.Bottom,
|
||||||
isConnectable: isConnectable,
|
isConnectable: isConnectable,
|
||||||
}),
|
}),
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "target",
|
type: "target",
|
||||||
position: Position.Top,
|
position: Position.Top,
|
||||||
isConnectable: isConnectable,
|
isConnectable: isConnectable,
|
||||||
|
|
@ -87,27 +81,7 @@ const ToolNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
|
|
||||||
// Простой компонент для узла типа 'error'
|
// Простой компонент для узла типа 'error'
|
||||||
const ErrorNode: React.FC<any> = ({ data, isConnectable }) => {
|
const ErrorNode: React.FC<any> = ({ data, isConnectable }) => {
|
||||||
return React.createElement('div', {
|
return React.createElement(React.Fragment, null,
|
||||||
className: 'react-flow__node-error'
|
|
||||||
},
|
|
||||||
React.createElement(Handle, {
|
|
||||||
type: "source",
|
|
||||||
position: Position.Bottom,
|
|
||||||
isConnectable: isConnectable,
|
|
||||||
}),
|
|
||||||
React.createElement(Handle, {
|
|
||||||
type: "target",
|
|
||||||
position: Position.Top,
|
|
||||||
isConnectable: isConnectable,
|
|
||||||
}),
|
|
||||||
data.label
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AssistantNode: React.FC<any> = ({ data, isConnectable }) => {
|
|
||||||
return React.createElement('div', {
|
|
||||||
className: 'react-flow__node-assistant' // Используем CSS класс для узла assistant
|
|
||||||
},
|
|
||||||
React.createElement(Handle, {
|
React.createElement(Handle, {
|
||||||
type: "source",
|
type: "source",
|
||||||
position: Position.Bottom,
|
position: Position.Bottom,
|
||||||
|
|
@ -128,7 +102,6 @@ const nodeTypes = {
|
||||||
llm: LLMNode,
|
llm: LLMNode,
|
||||||
tool: ToolNode,
|
tool: ToolNode,
|
||||||
error: ErrorNode,
|
error: ErrorNode,
|
||||||
assistant: AssistantNode,
|
|
||||||
// Если у тебя есть node.type === 'default', то можешь его тоже определить,
|
// Если у тебя есть node.type === 'default', то можешь его тоже определить,
|
||||||
// либо использовать встроенный 'default' React Flow.
|
// либо использовать встроенный 'default' React Flow.
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,14 @@
|
||||||
* прошлых разговоров, начала новых чатов и удаления записей графов.
|
* прошлых разговоров, начала новых чатов и удаления записей графов.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { EventBus } from '../utils/EventBus';
|
||||||
|
|
||||||
export class HistoryPanel {
|
export class HistoryPanel {
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
props: {
|
props: {
|
||||||
graphs: any[];
|
graphs: any[];
|
||||||
onGraphSelect: (graphId: string) => void;
|
onGraphSelect: (graphId: string) => void;
|
||||||
onNewChat: () => void;
|
eventBus: EventBus;
|
||||||
};
|
};
|
||||||
graphs: any[];
|
graphs: any[];
|
||||||
newChatButton: HTMLButtonElement;
|
newChatButton: HTMLButtonElement;
|
||||||
|
|
@ -22,7 +24,7 @@ export class HistoryPanel {
|
||||||
props: {
|
props: {
|
||||||
graphs: any[];
|
graphs: any[];
|
||||||
onGraphSelect: (graphId: string) => void;
|
onGraphSelect: (graphId: string) => void;
|
||||||
onNewChat: () => void;
|
eventBus: EventBus;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
@ -57,9 +59,7 @@ export class HistoryPanel {
|
||||||
|
|
||||||
setupEventListeners(): void {
|
setupEventListeners(): void {
|
||||||
this.newChatButton.addEventListener('click', () => {
|
this.newChatButton.addEventListener('click', () => {
|
||||||
if (this.props.onNewChat) {
|
this.props.eventBus.emit('new-chat');
|
||||||
this.props.onNewChat();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.deleteButton.addEventListener('click', () => {
|
this.deleteButton.addEventListener('click', () => {
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ export class ChatView extends ItemView {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Подписываемся на события
|
// Подписываемся на события
|
||||||
this.plugin.eventBus.on('node-selected', this.handleNodeSelected.bind(this));
|
this.plugin.eventBus.on('node-selected', this.handleNodeSelected.bind(this));
|
||||||
this.plugin.eventBus.on('new-chat', this.handleNewChat.bind(this));
|
this.plugin.eventBus.on('new-chat', this.handleNewChat.bind(this));
|
||||||
this.plugin.eventBus.on('graph-selected', this.handleGraphSelected.bind(this));
|
this.plugin.eventBus.on('graph-selected', this.handleGraphSelected.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClose(): Promise<void> {
|
async onClose(): Promise<void> {
|
||||||
if (this.chatPanel) {
|
if (this.chatPanel) {
|
||||||
|
|
|
||||||
|
|
@ -12,70 +12,70 @@ export const GRAPH_VIEW_TYPE = 'llm-agent-graph-view';
|
||||||
// ----------------------------------------------- Graph View ---------------------------------------------------------------
|
// ----------------------------------------------- Graph View ---------------------------------------------------------------
|
||||||
|
|
||||||
export class GraphView extends ItemView {
|
export class GraphView extends ItemView {
|
||||||
plugin: LLMAgentPlugin;
|
plugin: LLMAgentPlugin;
|
||||||
graphData: { nodes: any[], edges: any[] };
|
graphData: { nodes: any[]; edges: any[] };
|
||||||
currentNode: string | null;
|
currentNode: string | null;
|
||||||
graphsList: any[];
|
graphsList: any[];
|
||||||
selectedGraphId: string | null;
|
selectedGraphId: string | null;
|
||||||
|
|
||||||
// UI Elements
|
// UI Elements
|
||||||
historyPanel: HistoryPanel | null;
|
historyPanel: HistoryPanel | null;
|
||||||
historyContainer: HTMLDivElement;
|
historyContainer: HTMLDivElement;
|
||||||
graphContainer: HTMLDivElement;
|
graphContainer: HTMLDivElement;
|
||||||
reactRoot: ReactDOM.Root | null; // <-- ИСПРАВЛЕНО: Указываем тип для reactRoot
|
reactRoot: ReactDOM.Root | null; // <-- ИСПРАВЛЕНО: Указываем тип для reactRoot
|
||||||
|
|
||||||
constructor(leaf: WorkspaceLeaf, plugin: LLMAgentPlugin) {
|
constructor(leaf: WorkspaceLeaf, plugin: LLMAgentPlugin) {
|
||||||
super(leaf);
|
super(leaf);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.graphData = { nodes: [], edges: [] };
|
this.graphData = { nodes: [], edges: [] };
|
||||||
this.currentNode = null;
|
this.currentNode = null;
|
||||||
this.graphsList = [];
|
this.graphsList = [];
|
||||||
this.selectedGraphId = null;
|
this.selectedGraphId = null;
|
||||||
this.historyPanel = null;
|
this.historyPanel = null;
|
||||||
this.reactRoot = null; // Инициализируем null
|
this.reactRoot = null; // Инициализируем null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string} Тип представления.
|
* @returns {string} Тип представления.
|
||||||
*/
|
*/
|
||||||
getViewType(): string {
|
getViewType(): string {
|
||||||
return GRAPH_VIEW_TYPE;
|
return GRAPH_VIEW_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string} Отображаемое имя представления.
|
* @returns {string} Отображаемое имя представления.
|
||||||
*/
|
*/
|
||||||
getDisplayText(): string {
|
getDisplayText(): string {
|
||||||
return 'LLM Agent Graph';
|
return 'LLM Agent Graph';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string} Иконка представления.
|
* @returns {string} Иконка представления.
|
||||||
*/
|
*/
|
||||||
getIcon(): string {
|
getIcon(): string {
|
||||||
return 'brain-circuit';
|
return 'brain-circuit';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Вызывается при открытии представления. Инициализирует UI и загружает данные.
|
* Вызывается при открытии представления. Инициализирует UI и загружает данные.
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async onOpen(): Promise<void> {
|
async onOpen(): Promise<void> {
|
||||||
const container = this.containerEl.children[1] as HTMLElement;
|
const container = this.containerEl.children[1] as HTMLElement;
|
||||||
container.empty();
|
container.empty();
|
||||||
|
|
||||||
// Создаем основной контейнер с flexbox layout
|
// Создаем основной контейнер с flexbox layout
|
||||||
const mainContainer = container.createDiv('llm-agent-graph-main');
|
const mainContainer = container.createDiv('llm-agent-graph-main');
|
||||||
mainContainer.style.cssText = `
|
mainContainer.style.cssText = `
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--background-primary); /* Убедимся, что фон установлен */
|
background-color: var(--background-primary); /* Убедимся, что фон установлен */
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Левая панель для истории
|
// Левая панель для истории
|
||||||
this.historyContainer = mainContainer.createDiv('llm-agent-history-sidebar') as HTMLDivElement;
|
this.historyContainer = mainContainer.createDiv('llm-agent-history-sidebar') as HTMLDivElement;
|
||||||
this.historyContainer.style.cssText = `
|
this.historyContainer.style.cssText = `
|
||||||
width: 300px;
|
width: 300px;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
border-right: 1px solid var(--background-modifier-border); /* ИСПРАВЛЕНО: Использование переменной Obsidian */
|
border-right: 1px solid var(--background-modifier-border); /* ИСПРАВЛЕНО: Использование переменной Obsidian */
|
||||||
|
|
@ -83,198 +83,196 @@ export class GraphView extends ItemView {
|
||||||
background-color: var(--background-secondary); /* Убедимся, что фон установлен */
|
background-color: var(--background-secondary); /* Убедимся, что фон установлен */
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Правая панель для графа
|
// Правая панель для графа
|
||||||
this.graphContainer = mainContainer.createDiv('llm-agent-graph-container') as HTMLDivElement;
|
this.graphContainer = mainContainer.createDiv('llm-agent-graph-container') as HTMLDivElement;
|
||||||
this.graphContainer.style.cssText = `
|
this.graphContainer.style.cssText = `
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--background-primary); /* Убедимся, что фон установлен */
|
background-color: var(--background-primary); /* Убедимся, что фон установлен */
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Инициализируем панель истории
|
// Инициализируем панель истории
|
||||||
this.historyPanel = new HistoryPanel(this.historyContainer, {
|
this.historyPanel = new HistoryPanel(this.historyContainer, {
|
||||||
graphs: this.graphsList,
|
graphs: this.graphsList,
|
||||||
onGraphSelect: this.handleGraphSelect.bind(this),
|
onGraphSelect: this.handleGraphSelect.bind(this),
|
||||||
onNewChat: this.handleNewChat.bind(this)
|
eventBus: this.plugin.eventBus
|
||||||
});
|
});
|
||||||
|
|
||||||
// Инициализируем React Flow
|
// Инициализируем React Flow
|
||||||
this.initializeGraphPanel();
|
this.initializeGraphPanel();
|
||||||
|
|
||||||
// Подписываемся на события
|
// Подписываемся на события
|
||||||
this.plugin.eventBus.on('graph-updated', this.handleGraphUpdate.bind(this));
|
this.plugin.eventBus.on('graph-updated', this.handleGraphUpdate.bind(this));
|
||||||
this.plugin.eventBus.on('new-chat', this.handleNewChat.bind(this));
|
this.plugin.eventBus.on('new-chat', this.handleNewChat.bind(this));
|
||||||
|
|
||||||
// Загружаем список графов
|
// Загружаем список графов
|
||||||
await this.fetchGraphsList();
|
await this.fetchGraphsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Вызывается при закрытии представления. Очищает ресурсы.
|
* Вызывается при закрытии представления. Очищает ресурсы.
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async onClose(): Promise<void> {
|
async onClose(): Promise<void> {
|
||||||
if (this.historyPanel) {
|
if (this.historyPanel) {
|
||||||
this.historyPanel.destroy();
|
this.historyPanel.destroy();
|
||||||
this.historyPanel = null;
|
this.historyPanel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отмонтируем React-компонент
|
// Отмонтируем React-компонент
|
||||||
if (this.reactRoot) {
|
if (this.reactRoot) {
|
||||||
this.reactRoot.unmount();
|
this.reactRoot.unmount();
|
||||||
this.reactRoot = null;
|
this.reactRoot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.plugin.eventBus.off('graph-updated', this.handleGraphUpdate);
|
this.plugin.eventBus.off('graph-updated', this.handleGraphUpdate);
|
||||||
this.plugin.eventBus.off('new-chat', this.handleNewChat);
|
this.plugin.eventBus.off('new-chat', this.handleNewChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------- Graph Panel Integration --------------------------------------------------
|
// ----------------------------------------------- Graph Panel Integration --------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Инициализирует GraphPanelComponent (React компонент) в graphContainer.
|
* Инициализирует GraphPanelComponent (React компонент) в graphContainer.
|
||||||
* Использует ReactDOM.createRoot для React 18.
|
* Использует ReactDOM.createRoot для React 18.
|
||||||
*/
|
*/
|
||||||
initializeGraphPanel(): void {
|
initializeGraphPanel(): void {
|
||||||
// Создаем контейнер для React Flow
|
// Создаем контейнер для React Flow
|
||||||
// Убедимся, что id уникален или используем ref для React 18
|
// Убедимся, что id уникален или используем ref для React 18
|
||||||
this.graphContainer.empty(); // Очищаем контейнер перед добавлением нового элемента
|
this.graphContainer.empty(); // Очищаем контейнер перед добавлением нового элемента
|
||||||
const wrapper = this.graphContainer.createDiv();
|
const wrapper = this.graphContainer.createDiv();
|
||||||
wrapper.style.cssText = 'width: 100%; height: 100%;';
|
wrapper.style.cssText = 'width: 100%; height: 100%;';
|
||||||
|
|
||||||
|
if (!wrapper) {
|
||||||
|
console.error('Не удалось создать wrapper для монтирования React Flow.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wrapper) {
|
// Создаем корневой элемент React 18
|
||||||
console.error('Не удалось создать wrapper для монтирования React Flow.');
|
if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
|
||||||
return;
|
this.reactRoot = ReactDOM.createRoot(wrapper);
|
||||||
}
|
this.renderGraphPanel();
|
||||||
|
} else {
|
||||||
|
console.error('ReactDOM.createRoot не определен. Убедитесь, что "react-dom/client" правильно импортирован.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Создаем корневой элемент React 18
|
/**
|
||||||
if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
|
* Рендерит или обновляет GraphPanelComponent в DOM.
|
||||||
this.reactRoot = ReactDOM.createRoot(wrapper);
|
*/
|
||||||
this.renderGraphPanel();
|
renderGraphPanel(): void {
|
||||||
} else {
|
if (this.reactRoot) {
|
||||||
console.error('ReactDOM.createRoot не определен. Убедитесь, что "react-dom/client" правильно импортирован.');
|
this.reactRoot.render(
|
||||||
}
|
React.createElement(GraphPanelComponent, {
|
||||||
}
|
graphData: {
|
||||||
|
nodes: this.graphData.nodes,
|
||||||
|
edges: this.graphData.edges
|
||||||
|
},
|
||||||
|
onNodeClick: this.handleNodeClick.bind(this)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn('React root не инициализирован для рендера GraphPanelComponent.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ... (остальные методы API и Event Handlers без изменений)
|
||||||
|
// ----------------------------------------------- API Methods ---------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Рендерит или обновляет GraphPanelComponent в DOM.
|
* Загружает список всех графов с бэкенда.
|
||||||
*/
|
* @returns {Promise<void>}
|
||||||
renderGraphPanel(): void {
|
*/
|
||||||
if (this.reactRoot) {
|
async fetchGraphsList(): Promise<void> {
|
||||||
this.reactRoot.render(
|
try {
|
||||||
React.createElement(GraphPanelComponent, {
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs`);
|
||||||
graphData: {
|
if (!response.ok) {
|
||||||
nodes: this.graphData.nodes,
|
const errorText = await response.text();
|
||||||
edges: this.graphData.edges
|
throw new Error(`Ошибка загрузки списка графов: ${response.status} - ${errorText}`);
|
||||||
},
|
}
|
||||||
onNodeClick: this.handleNodeClick.bind(this)
|
const data = await response.json();
|
||||||
})
|
this.graphsList = data;
|
||||||
);
|
if (this.historyPanel) {
|
||||||
} else {
|
this.historyPanel.updateGraphs(this.graphsList);
|
||||||
console.warn('React root не инициализирован для рендера GraphPanelComponent.');
|
}
|
||||||
}
|
} catch (error) {
|
||||||
}
|
console.error('Ошибка загрузки списка графов:', error);
|
||||||
// ... (остальные методы API и Event Handlers без изменений)
|
// Optionally: show a notice to the user
|
||||||
// ----------------------------------------------- API Methods ---------------------------------------------------------------
|
// new Notice(`Ошибка загрузки списка графов: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Загружает список всех графов с бэкенда.
|
* Загружает данные конкретного графа по его ID.
|
||||||
* @returns {Promise<void>}
|
* @param {string} graphId - ID графа для загрузки.
|
||||||
*/
|
* @returns {Promise<void>}
|
||||||
async fetchGraphsList(): Promise<void> {
|
*/
|
||||||
try {
|
async fetchGraphData(graphId: string): Promise<void> {
|
||||||
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs`);
|
try {
|
||||||
if (!response.ok) {
|
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs/${graphId}`);
|
||||||
const errorText = await response.text();
|
if (!response.ok) {
|
||||||
throw new Error(`Ошибка загрузки списка графов: ${response.status} - ${errorText}`);
|
const errorText = await response.text();
|
||||||
}
|
throw new Error(`Ошибка загрузки данных графа: ${response.status} - ${errorText}`);
|
||||||
const data = await response.json();
|
}
|
||||||
this.graphsList = data;
|
const data = await response.json();
|
||||||
if (this.historyPanel) {
|
|
||||||
this.historyPanel.updateGraphs(this.graphsList);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Ошибка загрузки списка графов:', error);
|
|
||||||
// Optionally: show a notice to the user
|
|
||||||
// new Notice(`Ошибка загрузки списка графов: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
this.graphData = {
|
||||||
* Загружает данные конкретного графа по его ID.
|
nodes: data.graph_nodes || [],
|
||||||
* @param {string} graphId - ID графа для загрузки.
|
edges: data.graph_edges || []
|
||||||
* @returns {Promise<void>}
|
};
|
||||||
*/
|
this.currentNode = data.current_node_id;
|
||||||
async fetchGraphData(graphId: string): Promise<void> {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/graphs/${graphId}`);
|
|
||||||
if (!response.ok) {
|
|
||||||
const errorText = await response.text();
|
|
||||||
throw new Error(`Ошибка загрузки данных графа: ${response.status} - ${errorText}`);
|
|
||||||
}
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
this.graphData = {
|
// Перерендериваем граф
|
||||||
nodes: data.graph_nodes || [],
|
this.renderGraphPanel();
|
||||||
edges: data.graph_edges || []
|
} catch (error) {
|
||||||
};
|
console.error('Ошибка загрузки данных графа:', error);
|
||||||
this.currentNode = data.current_node_id;
|
// Optionally: show a notice to the user
|
||||||
|
// new Notice(`Ошибка загрузки данных графа: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Перерендериваем граф
|
// ----------------------------------------------- Event Handlers ------------------------------------------------------------
|
||||||
this.renderGraphPanel();
|
|
||||||
|
|
||||||
} catch (error) {
|
/**
|
||||||
console.error('Ошибка загрузки данных графа:', error);
|
* Обработчик клика по узлу графа.
|
||||||
// Optionally: show a notice to the user
|
* Устанавливает текущий узел и генерирует событие 'node-selected'.
|
||||||
// new Notice(`Ошибка загрузки данных графа: ${error.message}`);
|
* @param {string} nodeId - ID выбранного узла.
|
||||||
}
|
*/
|
||||||
}
|
handleNodeClick(nodeId: string): void {
|
||||||
|
this.currentNode = nodeId;
|
||||||
|
this.plugin.eventBus.emit('node-selected', { nodeId });
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------- Event Handlers ------------------------------------------------------------
|
/**
|
||||||
|
* Обработчик обновления данных графа (например, после нового сообщения).
|
||||||
|
* Обновляет `graphData` и перерендеривает граф.
|
||||||
|
* @param {{ graphData: { nodes: any[], edges: any[] }, currentNode: string | null }} data - Обновленные данные графа.
|
||||||
|
*/
|
||||||
|
handleGraphUpdate(data: { graphData: { nodes: any[]; edges: any[] }; currentNode: string | null }): void {
|
||||||
|
this.graphData = data.graphData;
|
||||||
|
this.currentNode = data.currentNode;
|
||||||
|
this.renderGraphPanel();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обработчик клика по узлу графа.
|
* Обработчик начала нового чата.
|
||||||
* Устанавливает текущий узел и генерирует событие 'node-selected'.
|
* Очищает текущие данные графа и перерендеривает его.
|
||||||
* @param {string} nodeId - ID выбранного узла.
|
*/
|
||||||
*/
|
handleNewChat(): void {
|
||||||
handleNodeClick(nodeId: string): void {
|
this.graphData = { nodes: [], edges: [] };
|
||||||
this.currentNode = nodeId;
|
this.currentNode = null;
|
||||||
this.plugin.eventBus.emit('node-selected', { nodeId });
|
this.selectedGraphId = null;
|
||||||
}
|
this.renderGraphPanel();
|
||||||
|
this.fetchGraphsList(); // Обновить список графов, чтобы показать новый пустой чат
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обработчик обновления данных графа (например, после нового сообщения).
|
* Обработчик выбора графа из панели истории.
|
||||||
* Обновляет `graphData` и перерендеривает граф.
|
* Устанавливает выбранный граф и загружает его данные.
|
||||||
* @param {{ graphData: { nodes: any[], edges: any[] }, currentNode: string | null }} data - Обновленные данные графа.
|
* @param {string} graphId - ID выбранного графа.
|
||||||
*/
|
*/
|
||||||
handleGraphUpdate(data: { graphData: { nodes: any[], edges: any[] }, currentNode: string | null }): void {
|
async handleGraphSelect(graphId: string): Promise<void> {
|
||||||
this.graphData = data.graphData;
|
this.selectedGraphId = graphId;
|
||||||
this.currentNode = data.currentNode;
|
await this.fetchGraphData(graphId);
|
||||||
this.renderGraphPanel();
|
// Также сообщаем ChatView, что выбран новый граф и он должен обновить свою историю
|
||||||
}
|
this.plugin.eventBus.emit('graph-selected', { graphId, currentNode: this.currentNode });
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* Обработчик начала нового чата.
|
|
||||||
* Очищает текущие данные графа и перерендеривает его.
|
|
||||||
*/
|
|
||||||
handleNewChat(): void {
|
|
||||||
this.graphData = { nodes: [], edges: [] };
|
|
||||||
this.currentNode = null;
|
|
||||||
this.selectedGraphId = null;
|
|
||||||
this.renderGraphPanel();
|
|
||||||
this.fetchGraphsList(); // Обновить список графов, чтобы показать новый пустой чат
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Обработчик выбора графа из панели истории.
|
|
||||||
* Устанавливает выбранный граф и загружает его данные.
|
|
||||||
* @param {string} graphId - ID выбранного графа.
|
|
||||||
*/
|
|
||||||
async handleGraphSelect(graphId: string): Promise<void> {
|
|
||||||
this.selectedGraphId = graphId;
|
|
||||||
await this.fetchGraphData(graphId);
|
|
||||||
// Также сообщаем ChatView, что выбран новый граф и он должен обновить свою историю
|
|
||||||
this.plugin.eventBus.emit('graph-selected', { graphId, currentNode: this.currentNode });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user