({ data: rawData, onClose }: { data: any, onClose: () => void })
| 355 | } |
| 356 | |
| 357 | export default function PRReviewer({ data: rawData, onClose }: { data: any, onClose: () => void }) { |
| 358 | const { theme, setTheme } = useTheme(); |
| 359 | const isDark = theme !== 'light'; |
| 360 | const pal = isDark ? PALETTE.dark : PALETTE.light; |
| 361 | |
| 362 | const data = useMemo(() => ({ |
| 363 | ...rawData, |
| 364 | nodes: (rawData?.nodes || []).map((node: any) => ({ |
| 365 | ...node, |
| 366 | name: getNodeDisplayName(node), |
| 367 | })), |
| 368 | links: rawData?.links || [], |
| 369 | files: rawData?.files || [], |
| 370 | }), [rawData]); |
| 371 | |
| 372 | const fgRef = useRef<any>(); |
| 373 | const [dimensions, setDimensions] = useState({ width: window.innerWidth, height: window.innerHeight }); |
| 374 | const [hoverNode, setHoverNode] = useState<any>(null); |
| 375 | const [searchQuery, setSearchQuery] = useState(""); |
| 376 | const [selectedFile, setSelectedFile] = useState<string | null>(null); |
| 377 | const [selectedNode, setSelectedNode] = useState<any>(null); |
| 378 | const [focusSet, setFocusSet] = useState<{ nodes: Set<any>, links: Set<any> } | null>(null); |
| 379 | |
| 380 | // PR Reviewer states |
| 381 | const [sidebarTab, setSidebarTab] = useState<'pr' | 'tree' | 'path' | 'config'>('pr'); |
| 382 | const isPathMode = sidebarTab === 'path'; |
| 383 | const showConfig = sidebarTab === 'config'; |
| 384 | |
| 385 | const [prComments, setPrComments] = useState<Record<string, { author: string; time: string; text: string }[]>>({}); |
| 386 | const [newCommentText, setNewCommentText] = useState(""); |
| 387 | |
| 388 | const handleAddComment = (nodeId: string) => { |
| 389 | if (!newCommentText.trim()) return; |
| 390 | const comment = { |
| 391 | author: "you", |
| 392 | time: "just now", |
| 393 | text: newCommentText.trim() |
| 394 | }; |
| 395 | setPrComments(prev => ({ |
| 396 | ...prev, |
| 397 | [nodeId]: [...(prev[nodeId] || []), comment] |
| 398 | })); |
| 399 | setNewCommentText(""); |
| 400 | toast.success("Review note saved locally"); |
| 401 | }; |
| 402 | |
| 403 | // Publish and Export parameters |
| 404 | const { owner, repo } = useParams(); |
| 405 | const defaultRepoName = data.metadata?.repo || (owner && repo ? `${owner}/${repo}` : ""); |
| 406 | const [showPublishModal, setShowPublishModal] = useState(false); |
| 407 | const [showChatGPTModal, setShowChatGPTModal] = useState(false); |
| 408 | const [publishRepo, setPublishRepo] = useState(""); |
| 409 | const [publishVersion, setPublishVersion] = useState("1.0.0"); |
| 410 | const [isPublishing, setIsPublishing] = useState(false); |
| 411 | const [showMobileMenu, setShowMobileMenu] = useState(false); |
| 412 | |
| 413 | // Dynamic ChatGPT Connection URL with pre-filled version-scoped query |
| 414 | const metadata = data.metadata || {}; |
nothing calls this directly
no test coverage detected