Spaces:
Running
Running
| import React from "react"; | |
| interface InteractiveSystemSummaryProps { | |
| summary: string; | |
| onEntityClick: (id: string) => void; | |
| selectedNodeId?: string | null; | |
| } | |
| export const InteractiveSystemSummary: React.FC< | |
| InteractiveSystemSummaryProps | |
| > = ({ summary, onEntityClick, selectedNodeId }) => { | |
| const parseSummary = (text: string) => { | |
| const regex = /[`'β]([^`'β]+)[`'β][^()]*\(([^)]+)\)/g; | |
| const parts = []; | |
| let lastIndex = 0; | |
| let match; | |
| while ((match = regex.exec(text)) !== null) { | |
| if (match.index > lastIndex) { | |
| parts.push(text.substring(lastIndex, match.index)); | |
| } | |
| const [fullMatch, name, id] = match; | |
| if (name && id) { | |
| const isSelected = selectedNodeId === id; | |
| parts.push( | |
| <a | |
| key={id} | |
| href="#" | |
| className={`transition-colors duration-200 ${ | |
| isSelected | |
| ? "text-blue-600 bg-blue-100 dark:bg-blue-900/30 dark:text-blue-400 px-1 py-0.5 rounded font-medium underline" | |
| : "text-blue-500 hover:underline hover:text-blue-600" | |
| }`} | |
| onClick={(e) => { | |
| e.preventDefault(); | |
| onEntityClick(id); | |
| }} | |
| > | |
| {name} | |
| </a> | |
| ); | |
| } else { | |
| parts.push(fullMatch); | |
| } | |
| lastIndex = regex.lastIndex; | |
| } | |
| if (lastIndex < text.length) { | |
| parts.push(text.substring(lastIndex)); | |
| } | |
| return parts; | |
| }; | |
| return ( | |
| <p className="text-sm text-muted-foreground">{parseSummary(summary)}</p> | |
| ); | |
| }; | |