yangdx
commited on
Commit
·
2ea23b2
1
Parent(s):
df3f806
Remove grapOperation.ts
Browse files
lightrag_webui/src/components/graph/EditablePropertyRow.tsx
CHANGED
@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'
|
|
2 |
import { useTranslation } from 'react-i18next'
|
3 |
import { toast } from 'sonner'
|
4 |
import { updateEntity, updateRelation, checkEntityNameExists } from '@/api/lightrag'
|
5 |
-
import {
|
6 |
import { PropertyName, EditIcon, PropertyValue } from './PropertyRowComponents'
|
7 |
import PropertyEditDialog from './PropertyEditDialog'
|
8 |
|
@@ -85,12 +85,22 @@ const EditablePropertyRow = ({
|
|
85 |
}
|
86 |
|
87 |
await updateEntity(entityId, updatedData, true)
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
89 |
toast.success(t('graphPanel.propertiesView.success.entityUpdated'))
|
90 |
} else if (entityType === 'edge' && sourceId && targetId && edgeId && dynamicId) {
|
91 |
const updatedData = { [name]: value }
|
92 |
await updateRelation(sourceId, targetId, updatedData)
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
94 |
toast.success(t('graphPanel.propertiesView.success.relationUpdated'))
|
95 |
}
|
96 |
|
|
|
2 |
import { useTranslation } from 'react-i18next'
|
3 |
import { toast } from 'sonner'
|
4 |
import { updateEntity, updateRelation, checkEntityNameExists } from '@/api/lightrag'
|
5 |
+
import { useGraphStore } from '@/stores/graph'
|
6 |
import { PropertyName, EditIcon, PropertyValue } from './PropertyRowComponents'
|
7 |
import PropertyEditDialog from './PropertyEditDialog'
|
8 |
|
|
|
85 |
}
|
86 |
|
87 |
await updateEntity(entityId, updatedData, true)
|
88 |
+
try {
|
89 |
+
await useGraphStore.getState().updateNodeAndSelect(nodeId, entityId, name, value)
|
90 |
+
} catch (error) {
|
91 |
+
console.error('Error updating node in graph:', error)
|
92 |
+
throw new Error('Failed to update node in graph')
|
93 |
+
}
|
94 |
toast.success(t('graphPanel.propertiesView.success.entityUpdated'))
|
95 |
} else if (entityType === 'edge' && sourceId && targetId && edgeId && dynamicId) {
|
96 |
const updatedData = { [name]: value }
|
97 |
await updateRelation(sourceId, targetId, updatedData)
|
98 |
+
try {
|
99 |
+
await useGraphStore.getState().updateEdgeAndSelect(edgeId, dynamicId, sourceId, targetId, name, value)
|
100 |
+
} catch (error) {
|
101 |
+
console.error(`Error updating edge ${sourceId}->${targetId} in graph:`, error)
|
102 |
+
throw new Error('Failed to update edge in graph')
|
103 |
+
}
|
104 |
toast.success(t('graphPanel.propertiesView.success.relationUpdated'))
|
105 |
}
|
106 |
|
lightrag_webui/src/stores/graph.ts
CHANGED
@@ -136,7 +136,7 @@ interface GraphState {
|
|
136 |
// Version counter to trigger data refresh
|
137 |
graphDataVersion: number
|
138 |
incrementGraphDataVersion: () => void
|
139 |
-
|
140 |
// Methods for updating graph elements and UI state together
|
141 |
updateNodeAndSelect: (nodeId: string, entityId: string, propertyName: string, newValue: string) => Promise<void>
|
142 |
updateEdgeAndSelect: (edgeId: string, dynamicId: string, sourceId: string, targetId: string, propertyName: string, newValue: string) => Promise<void>
|
@@ -252,40 +252,40 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
252 |
// Get current state
|
253 |
const state = get()
|
254 |
const { sigmaGraph, rawGraph } = state
|
255 |
-
|
256 |
// Validate graph state
|
257 |
if (!sigmaGraph || !rawGraph || !sigmaGraph.hasNode(nodeId)) {
|
258 |
return
|
259 |
}
|
260 |
-
|
261 |
try {
|
262 |
const nodeAttributes = sigmaGraph.getNodeAttributes(nodeId)
|
263 |
-
|
264 |
console.log('updateNodeAndSelect', nodeId, entityId, propertyName, newValue)
|
265 |
-
|
266 |
// For entity_id changes (node renaming) with NetworkX graph storage
|
267 |
if ((nodeId === entityId) && (propertyName === 'entity_id')) {
|
268 |
// Create new node with updated ID but same attributes
|
269 |
sigmaGraph.addNode(newValue, { ...nodeAttributes, label: newValue })
|
270 |
-
|
271 |
const edgesToUpdate: EdgeToUpdate[] = []
|
272 |
-
|
273 |
// Process all edges connected to this node
|
274 |
sigmaGraph.forEachEdge(nodeId, (edge, attributes, source, target) => {
|
275 |
const otherNode = source === nodeId ? target : source
|
276 |
const isOutgoing = source === nodeId
|
277 |
-
|
278 |
// Get original edge dynamic ID for later reference
|
279 |
const originalEdgeDynamicId = edge
|
280 |
const edgeIndexInRawGraph = rawGraph.edgeDynamicIdMap[originalEdgeDynamicId]
|
281 |
-
|
282 |
// Create new edge with updated node reference
|
283 |
const newEdgeId = sigmaGraph.addEdge(
|
284 |
isOutgoing ? newValue : otherNode,
|
285 |
isOutgoing ? otherNode : newValue,
|
286 |
attributes
|
287 |
)
|
288 |
-
|
289 |
// Track edges that need updating in the raw graph
|
290 |
if (edgeIndexInRawGraph !== undefined) {
|
291 |
edgesToUpdate.push({
|
@@ -294,14 +294,14 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
294 |
edgeIndex: edgeIndexInRawGraph
|
295 |
})
|
296 |
}
|
297 |
-
|
298 |
// Remove the old edge
|
299 |
sigmaGraph.dropEdge(edge)
|
300 |
})
|
301 |
-
|
302 |
// Remove the old node after all edges are processed
|
303 |
sigmaGraph.dropNode(nodeId)
|
304 |
-
|
305 |
// Update node reference in raw graph data
|
306 |
const nodeIndex = rawGraph.nodeIdMap[nodeId]
|
307 |
if (nodeIndex !== undefined) {
|
@@ -311,7 +311,7 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
311 |
delete rawGraph.nodeIdMap[nodeId]
|
312 |
rawGraph.nodeIdMap[newValue] = nodeIndex
|
313 |
}
|
314 |
-
|
315 |
// Update all edge references in raw graph data
|
316 |
edgesToUpdate.forEach(({ originalDynamicId, newEdgeId, edgeIndex }) => {
|
317 |
if (rawGraph.edges[edgeIndex]) {
|
@@ -322,14 +322,14 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
322 |
if (rawGraph.edges[edgeIndex].target === nodeId) {
|
323 |
rawGraph.edges[edgeIndex].target = newValue
|
324 |
}
|
325 |
-
|
326 |
// Update dynamic ID mappings
|
327 |
rawGraph.edges[edgeIndex].dynamicId = newEdgeId
|
328 |
delete rawGraph.edgeDynamicIdMap[originalDynamicId]
|
329 |
rawGraph.edgeDynamicIdMap[newEdgeId] = edgeIndex
|
330 |
}
|
331 |
})
|
332 |
-
|
333 |
// Update selected node in store
|
334 |
set({ selectedNode: newValue, moveToSelectedNode: true })
|
335 |
} else {
|
@@ -342,7 +342,7 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
342 |
sigmaGraph.setNodeAttribute(String(nodeId), 'label', newValue)
|
343 |
}
|
344 |
}
|
345 |
-
|
346 |
// Trigger a re-render by incrementing the version counter
|
347 |
set((state) => ({ graphDataVersion: state.graphDataVersion + 1 }))
|
348 |
}
|
@@ -351,17 +351,17 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
351 |
throw new Error('Failed to update node in graph')
|
352 |
}
|
353 |
},
|
354 |
-
|
355 |
updateEdgeAndSelect: async (edgeId: string, dynamicId: string, sourceId: string, targetId: string, propertyName: string, newValue: string) => {
|
356 |
// Get current state
|
357 |
const state = get()
|
358 |
const { sigmaGraph, rawGraph } = state
|
359 |
-
|
360 |
// Validate graph state
|
361 |
if (!sigmaGraph || !rawGraph) {
|
362 |
return
|
363 |
}
|
364 |
-
|
365 |
try {
|
366 |
const edgeIndex = rawGraph.edgeIdMap[String(edgeId)]
|
367 |
if (edgeIndex !== undefined && rawGraph.edges[edgeIndex]) {
|
@@ -370,10 +370,10 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
|
|
370 |
sigmaGraph.setEdgeAttribute(dynamicId, 'label', newValue)
|
371 |
}
|
372 |
}
|
373 |
-
|
374 |
// Trigger a re-render by incrementing the version counter
|
375 |
set((state) => ({ graphDataVersion: state.graphDataVersion + 1 }))
|
376 |
-
|
377 |
// Update selected edge in store to ensure UI reflects changes
|
378 |
set({ selectedEdge: dynamicId })
|
379 |
} catch (error) {
|
|
|
136 |
// Version counter to trigger data refresh
|
137 |
graphDataVersion: number
|
138 |
incrementGraphDataVersion: () => void
|
139 |
+
|
140 |
// Methods for updating graph elements and UI state together
|
141 |
updateNodeAndSelect: (nodeId: string, entityId: string, propertyName: string, newValue: string) => Promise<void>
|
142 |
updateEdgeAndSelect: (edgeId: string, dynamicId: string, sourceId: string, targetId: string, propertyName: string, newValue: string) => Promise<void>
|
|
|
252 |
// Get current state
|
253 |
const state = get()
|
254 |
const { sigmaGraph, rawGraph } = state
|
255 |
+
|
256 |
// Validate graph state
|
257 |
if (!sigmaGraph || !rawGraph || !sigmaGraph.hasNode(nodeId)) {
|
258 |
return
|
259 |
}
|
260 |
+
|
261 |
try {
|
262 |
const nodeAttributes = sigmaGraph.getNodeAttributes(nodeId)
|
263 |
+
|
264 |
console.log('updateNodeAndSelect', nodeId, entityId, propertyName, newValue)
|
265 |
+
|
266 |
// For entity_id changes (node renaming) with NetworkX graph storage
|
267 |
if ((nodeId === entityId) && (propertyName === 'entity_id')) {
|
268 |
// Create new node with updated ID but same attributes
|
269 |
sigmaGraph.addNode(newValue, { ...nodeAttributes, label: newValue })
|
270 |
+
|
271 |
const edgesToUpdate: EdgeToUpdate[] = []
|
272 |
+
|
273 |
// Process all edges connected to this node
|
274 |
sigmaGraph.forEachEdge(nodeId, (edge, attributes, source, target) => {
|
275 |
const otherNode = source === nodeId ? target : source
|
276 |
const isOutgoing = source === nodeId
|
277 |
+
|
278 |
// Get original edge dynamic ID for later reference
|
279 |
const originalEdgeDynamicId = edge
|
280 |
const edgeIndexInRawGraph = rawGraph.edgeDynamicIdMap[originalEdgeDynamicId]
|
281 |
+
|
282 |
// Create new edge with updated node reference
|
283 |
const newEdgeId = sigmaGraph.addEdge(
|
284 |
isOutgoing ? newValue : otherNode,
|
285 |
isOutgoing ? otherNode : newValue,
|
286 |
attributes
|
287 |
)
|
288 |
+
|
289 |
// Track edges that need updating in the raw graph
|
290 |
if (edgeIndexInRawGraph !== undefined) {
|
291 |
edgesToUpdate.push({
|
|
|
294 |
edgeIndex: edgeIndexInRawGraph
|
295 |
})
|
296 |
}
|
297 |
+
|
298 |
// Remove the old edge
|
299 |
sigmaGraph.dropEdge(edge)
|
300 |
})
|
301 |
+
|
302 |
// Remove the old node after all edges are processed
|
303 |
sigmaGraph.dropNode(nodeId)
|
304 |
+
|
305 |
// Update node reference in raw graph data
|
306 |
const nodeIndex = rawGraph.nodeIdMap[nodeId]
|
307 |
if (nodeIndex !== undefined) {
|
|
|
311 |
delete rawGraph.nodeIdMap[nodeId]
|
312 |
rawGraph.nodeIdMap[newValue] = nodeIndex
|
313 |
}
|
314 |
+
|
315 |
// Update all edge references in raw graph data
|
316 |
edgesToUpdate.forEach(({ originalDynamicId, newEdgeId, edgeIndex }) => {
|
317 |
if (rawGraph.edges[edgeIndex]) {
|
|
|
322 |
if (rawGraph.edges[edgeIndex].target === nodeId) {
|
323 |
rawGraph.edges[edgeIndex].target = newValue
|
324 |
}
|
325 |
+
|
326 |
// Update dynamic ID mappings
|
327 |
rawGraph.edges[edgeIndex].dynamicId = newEdgeId
|
328 |
delete rawGraph.edgeDynamicIdMap[originalDynamicId]
|
329 |
rawGraph.edgeDynamicIdMap[newEdgeId] = edgeIndex
|
330 |
}
|
331 |
})
|
332 |
+
|
333 |
// Update selected node in store
|
334 |
set({ selectedNode: newValue, moveToSelectedNode: true })
|
335 |
} else {
|
|
|
342 |
sigmaGraph.setNodeAttribute(String(nodeId), 'label', newValue)
|
343 |
}
|
344 |
}
|
345 |
+
|
346 |
// Trigger a re-render by incrementing the version counter
|
347 |
set((state) => ({ graphDataVersion: state.graphDataVersion + 1 }))
|
348 |
}
|
|
|
351 |
throw new Error('Failed to update node in graph')
|
352 |
}
|
353 |
},
|
354 |
+
|
355 |
updateEdgeAndSelect: async (edgeId: string, dynamicId: string, sourceId: string, targetId: string, propertyName: string, newValue: string) => {
|
356 |
// Get current state
|
357 |
const state = get()
|
358 |
const { sigmaGraph, rawGraph } = state
|
359 |
+
|
360 |
// Validate graph state
|
361 |
if (!sigmaGraph || !rawGraph) {
|
362 |
return
|
363 |
}
|
364 |
+
|
365 |
try {
|
366 |
const edgeIndex = rawGraph.edgeIdMap[String(edgeId)]
|
367 |
if (edgeIndex !== undefined && rawGraph.edges[edgeIndex]) {
|
|
|
370 |
sigmaGraph.setEdgeAttribute(dynamicId, 'label', newValue)
|
371 |
}
|
372 |
}
|
373 |
+
|
374 |
// Trigger a re-render by incrementing the version counter
|
375 |
set((state) => ({ graphDataVersion: state.graphDataVersion + 1 }))
|
376 |
+
|
377 |
// Update selected edge in store to ensure UI reflects changes
|
378 |
set({ selectedEdge: dynamicId })
|
379 |
} catch (error) {
|
lightrag_webui/src/utils/graphOperations.ts
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
import { useGraphStore } from '@/stores/graph'
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Update node in the graph visualization
|
5 |
-
* This function is now a wrapper around the store's updateNodeAndSelect method
|
6 |
-
*
|
7 |
-
* @param nodeId - ID of the node to update
|
8 |
-
* @param entityId - ID of the entity
|
9 |
-
* @param propertyName - Name of the property being updated
|
10 |
-
* @param newValue - New value for the property
|
11 |
-
*/
|
12 |
-
export const updateGraphNode = async (nodeId: string, entityId: string, propertyName: string, newValue: string) => {
|
13 |
-
try {
|
14 |
-
// Call the store method that handles both data update and UI state
|
15 |
-
await useGraphStore.getState().updateNodeAndSelect(nodeId, entityId, propertyName, newValue)
|
16 |
-
} catch (error) {
|
17 |
-
console.error('Error updating node in graph:', error)
|
18 |
-
throw new Error('Failed to update node in graph')
|
19 |
-
}
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Update edge in the graph visualization
|
24 |
-
* This function is now a wrapper around the store's updateEdgeAndSelect method
|
25 |
-
*
|
26 |
-
* @param edgeId - ID of the edge
|
27 |
-
* @param dynamicId - Dynamic ID of the edge in sigma graph
|
28 |
-
* @param sourceId - ID of the source node
|
29 |
-
* @param targetId - ID of the target node
|
30 |
-
* @param propertyName - Name of the property being updated
|
31 |
-
* @param newValue - New value for the property
|
32 |
-
*/
|
33 |
-
export const updateGraphEdge = async (edgeId: string, dynamicId: string, sourceId: string, targetId: string, propertyName: string, newValue: string) => {
|
34 |
-
try {
|
35 |
-
// Call the store method that handles both data update and UI state
|
36 |
-
await useGraphStore.getState().updateEdgeAndSelect(edgeId, dynamicId, sourceId, targetId, propertyName, newValue)
|
37 |
-
} catch (error) {
|
38 |
-
console.error(`Error updating edge ${sourceId}->${targetId} in graph:`, error)
|
39 |
-
throw new Error('Failed to update edge in graph')
|
40 |
-
}
|
41 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|