| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  | import { useState, useEffect } from 'react' | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							|  |  |  | import { toast } from 'sonner' | 
					
						
							|  |  |  | import { updateEntity, updateRelation, checkEntityNameExists } from '@/api/lightrag' | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  | import { updateGraphNode, updateGraphEdge } from '@/utils/graphOperations' | 
					
						
							|  |  |  | import { PropertyName, EditIcon, PropertyValue } from './PropertyRowComponents' | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  | import PropertyEditDialog from './PropertyEditDialog' | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:13:23 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Interface for the EditablePropertyRow component props | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | interface EditablePropertyRowProps { | 
					
						
							| 
									
										
										
										
											2025-04-13 11:13:23 +08:00
										 |  |  |   name: string                  // Property name to display and edit
 | 
					
						
							|  |  |  |   value: any                    // Initial value of the property
 | 
					
						
							|  |  |  |   onClick?: () => void          // Optional click handler for the property value
 | 
					
						
							|  |  |  |   entityId?: string             // ID of the entity (for node type)
 | 
					
						
							|  |  |  |   entityType?: 'node' | 'edge'  // Type of graph entity
 | 
					
						
							|  |  |  |   sourceId?: string            // Source node ID (for edge type)
 | 
					
						
							|  |  |  |   targetId?: string            // Target node ID (for edge type)
 | 
					
						
							|  |  |  |   onValueChange?: (newValue: any) => void  // Optional callback when value changes
 | 
					
						
							|  |  |  |   isEditable?: boolean         // Whether this property can be edited
 | 
					
						
							| 
									
										
										
										
											2025-04-14 14:45:37 +08:00
										 |  |  |   tooltip?: string             // Optional tooltip to display on hover
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:13:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  |  * EditablePropertyRow component that supports editing property values | 
					
						
							| 
									
										
										
										
											2025-04-13 11:13:23 +08:00
										 |  |  |  * This component is used in the graph properties panel to display and edit entity properties | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | const EditablePropertyRow = ({ | 
					
						
							|  |  |  |   name, | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |   value: initialValue, | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |   onClick, | 
					
						
							|  |  |  |   entityId, | 
					
						
							|  |  |  |   entityType, | 
					
						
							|  |  |  |   sourceId, | 
					
						
							|  |  |  |   targetId, | 
					
						
							|  |  |  |   onValueChange, | 
					
						
							| 
									
										
										
										
											2025-04-14 14:45:37 +08:00
										 |  |  |   isEditable = false, | 
					
						
							|  |  |  |   tooltip | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | }: EditablePropertyRowProps) => { | 
					
						
							|  |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const [isEditing, setIsEditing] = useState(false) | 
					
						
							|  |  |  |   const [isSubmitting, setIsSubmitting] = useState(false) | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |   const [currentValue, setCurrentValue] = useState(initialValue) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |   useEffect(() => { | 
					
						
							|  |  |  |     setCurrentValue(initialValue) | 
					
						
							|  |  |  |   }, [initialValue]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |   const handleEditClick = () => { | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |     if (isEditable && !isEditing) { | 
					
						
							|  |  |  |       setIsEditing(true) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |   const handleCancel = () => { | 
					
						
							|  |  |  |     setIsEditing(false) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |   const handleSave = async (value: string) => { | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  |     if (isSubmitting || value === String(currentValue)) { | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |       setIsEditing(false) | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |     setIsSubmitting(true) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |     try { | 
					
						
							|  |  |  |       if (entityType === 'node' && entityId) { | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |         let updatedData = { [name]: value } | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |         if (name === 'entity_id') { | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |           const exists = await checkEntityNameExists(value) | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |           if (exists) { | 
					
						
							|  |  |  |             toast.error(t('graphPanel.propertiesView.errors.duplicateName')) | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |           updatedData = { 'entity_name': value } | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-13 11:13:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |         await updateEntity(entityId, updatedData, true) | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |         await updateGraphNode(entityId, name, value) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |         toast.success(t('graphPanel.propertiesView.success.entityUpdated')) | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  |       } else if (entityType === 'edge' && sourceId && targetId) { | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |         const updatedData = { [name]: value } | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |         await updateRelation(sourceId, targetId, updatedData) | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |         await updateGraphEdge(sourceId, targetId, name, value) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |         toast.success(t('graphPanel.propertiesView.success.relationUpdated')) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |       setIsEditing(false) | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |       setCurrentValue(value) | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  |       onValueChange?.(value) | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |     } catch (error) { | 
					
						
							| 
									
										
										
										
											2025-04-12 13:17:09 +08:00
										 |  |  |       console.error('Error updating property:', error) | 
					
						
							| 
									
										
										
										
											2025-04-12 15:09:44 +08:00
										 |  |  |       toast.error(t('graphPanel.propertiesView.errors.updateFailed')) | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |     } finally { | 
					
						
							|  |  |  |       setIsSubmitting(false) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |     <div className="flex items-center gap-1"> | 
					
						
							| 
									
										
										
										
											2025-04-14 10:13:54 +08:00
										 |  |  |       <PropertyName name={name} /> | 
					
						
							|  |  |  |       <EditIcon onClick={handleEditClick} />: | 
					
						
							| 
									
										
										
										
											2025-04-14 14:53:13 +08:00
										 |  |  |       <PropertyValue | 
					
						
							|  |  |  |         value={currentValue} | 
					
						
							|  |  |  |         onClick={onClick} | 
					
						
							| 
									
										
										
										
											2025-04-14 14:45:37 +08:00
										 |  |  |         tooltip={tooltip || (typeof currentValue === 'string' ? currentValue : JSON.stringify(currentValue, null, 2))} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2025-04-13 23:32:35 +08:00
										 |  |  |       <PropertyEditDialog | 
					
						
							|  |  |  |         isOpen={isEditing} | 
					
						
							|  |  |  |         onClose={handleCancel} | 
					
						
							|  |  |  |         onSave={handleSave} | 
					
						
							|  |  |  |         propertyName={name} | 
					
						
							|  |  |  |         initialValue={String(currentValue)} | 
					
						
							|  |  |  |         isSubmitting={isSubmitting} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2025-04-12 00:48:19 +08:00
										 |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default EditablePropertyRow |