11import { Handle, Position } from "@xyflow/react";
2- import { memo, useEffect, useMemo } from "react";
2+ import { memo, useCallback, useEffect, useMemo } from "react";
33
44import { InputValueEditor } from "@/components/Editor/IOEditor/InputValueEditor";
55import { OutputNameEditor } from "@/components/Editor/IOEditor/OutputNameEditor";
66import { getOutputConnectedDetails } from "@/components/Editor/utils/getOutputConnectedDetails";
77import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
88import { BlockStack, InlineStack } from "@/components/ui/layout";
99import { Paragraph } from "@/components/ui/typography";
10+ import { useNodeManager } from "@/hooks/useNodeManager";
1011import { cn } from "@/lib/utils";
1112import { useComponentSpec } from "@/providers/ComponentSpecProvider";
1213import { useContextPanel } from "@/providers/ContextPanelProvider";
1314import type { IONodeData } from "@/types/nodes";
1415import type { InputSpec, TypeSpecType } from "@/utils/componentSpec";
16+ import { ENABLE_DEBUG_MODE } from "@/utils/constants";
17+ import {
18+ inputNameToInputId,
19+ outputNameToOutputId,
20+ } from "@/utils/nodes/nodeIdUtils";
1521
1622interface IONodeProps {
1723 type: "input" | "output";
@@ -21,6 +27,7 @@ interface IONodeProps {
2127}
2228
2329const IONode = ({ type, data, selected = false }: IONodeProps) => {
30+ const { getInputNodeId, getOutputNodeId } = useNodeManager();
2431 const { graphSpec, componentSpec } = useComponentSpec();
2532 const { setContent, clearContent } = useContextPanel();
2633
@@ -51,6 +58,24 @@ const IONode = ({ type, data, selected = false }: IONodeProps) => {
5158 [componentSpec.outputs, spec.name],
5259 );
5360
61+ const nodeId = isInput
62+ ? getInputNodeId(inputNameToInputId(spec.name))
63+ : getOutputNodeId(outputNameToOutputId(spec.name));
64+
65+ const nodeHandleId = isInput
66+ ? getInputNodeId(inputNameToInputId(spec.name + "handle"))
67+ : getOutputNodeId(outputNameToOutputId(spec.name + "handle"));
68+
69+ const handleHandleClick = useCallback(() => {
70+ if (ENABLE_DEBUG_MODE) {
71+ console.log(`${isInput ? "Input" : "Output"} Handle clicked:`, {
72+ name: isInput ? input?.name : output?.name,
73+ nodeId,
74+ nodeHandleId,
75+ });
76+ }
77+ }, [isInput, input, output, nodeId, nodeHandleId]);
78+
5479 useEffect(() => {
5580 if (selected) {
5681 if (input && isInput) {
@@ -112,6 +137,11 @@ const IONode = ({ type, data, selected = false }: IONodeProps) => {
112137 <Card className={cn("border-2 max-w-[300px] p-0", borderColor)}>
113138 <CardHeader className="px-2 py-2.5">
114139 <CardTitle className="break-words">{spec.name}</CardTitle>
140+ {ENABLE_DEBUG_MODE && (
141+ <Paragraph size="xs" tone="subdued">
142+ Node Id: {nodeId}
143+ </Paragraph>
144+ )}
115145 </CardHeader>
116146 <CardContent className="p-2 max-w-[250px]">
117147 <BlockStack gap="2">
@@ -147,9 +177,11 @@ const IONode = ({ type, data, selected = false }: IONodeProps) => {
147177 </InlineStack>
148178 </BlockStack>
149179 <Handle
180+ id={nodeHandleId}
150181 type={handleType}
151182 position={handlePosition}
152183 className={cn(handleDefaultClassName, handleClassName)}
184+ onClick={handleHandleClick}
153185 />
154186 </CardContent>
155187 </Card>
0 commit comments