-
+ {/* Top handle — skip for Root node since nothing connects above it */}
+ {!isRoot && (
+ <>
+
+
IN
+ >
+ )}
+
-
-
-
{data.label}
-
{data.registrationName}
+
+
+
+
+
{primaryLabel}
+ {secondaryLabel && secondaryLabel !== primaryLabel && (
+
{secondaryLabel}
+ )}
+ {!secondaryLabel || secondaryLabel === primaryLabel ? (
+
{data.registrationName}
+ ) : (
+
{data.registrationName}
+ )}
+
+
+ {/* Inline port parameters */}
+ {portEntries.length > 0 && (
+
+ {visiblePorts.map(([key, value]) => {
+ const dir = getPortDirection(key, data.portDirections)
+ return (
+
+ {dir && (
+
+ {dir === 'input' ? 'IN' : 'OUT'}
+
+ )}
+ {key}
+ {value && : {value}}
+
+ )
+ })}
+ {hiddenCount > 0 && (
+
...+{hiddenCount} more
+ )}
+
+ )}
+
{data.breakpoint &&
}
{status !== 'IDLE' &&
{status}}
+
+ {/* Root badge */}
+ {isRoot &&
ROOT}
+
+ {/* Bottom handle with OUT label — only if node can have children */}
{canHaveChildren(data.nodeType) && (
-
+ <>
+
+
OUT
+ >
)}
)
diff --git a/src/components/Inspector.tsx b/src/components/Inspector.tsx
index 3179ea9..32a30bc 100644
--- a/src/components/Inspector.tsx
+++ b/src/components/Inspector.tsx
@@ -1,6 +1,6 @@
import { AlertCircle, Braces, Plus, Trash2, X } from 'lucide-react'
-import { CATEGORY_LABELS } from '../lib/catalog'
-import type { BehaviorNode, BehaviorTreeDocument, ValidationIssue } from '../types'
+import { useI18n } from '../context/I18nContext'
+import type { BehaviorNode, BehaviorTreeDocument, PortDirection, ValidationIssue } from '../types'
interface InspectorProps {
document: BehaviorTreeDocument
@@ -13,6 +13,8 @@ interface InspectorProps {
}
export function Inspector({ document, selectedNode, issues, onUpdateDocument, onUpdateNode, onDeleteNode, onSelectIssue }: InspectorProps) {
+ const { t } = useI18n()
+
const updatePort = (oldKey: string, key: string, value: string) => {
if (!selectedNode) return
const ports = { ...selectedNode.data.ports }
@@ -21,11 +23,27 @@ export function Inspector({ document, selectedNode, issues, onUpdateDocument, on
onUpdateNode(selectedNode.id, { ports })
}
+ const updatePortDirection = (key: string, direction: PortDirection | '') => {
+ if (!selectedNode) return
+ const portDirections = { ...(selectedNode.data.portDirections || {}) }
+ if (direction) {
+ portDirections[key] = direction
+ } else {
+ delete portDirections[key]
+ }
+ onUpdateNode(selectedNode.id, { portDirections: Object.keys(portDirections).length > 0 ? portDirections : undefined })
+ }
+
const removePort = (key: string) => {
if (!selectedNode) return
const ports = { ...selectedNode.data.ports }
delete ports[key]
- onUpdateNode(selectedNode.id, { ports })
+ const portDirections = selectedNode.data.portDirections ? { ...selectedNode.data.portDirections } : {}
+ delete portDirections[key]
+ onUpdateNode(selectedNode.id, {
+ ports,
+ portDirections: Object.keys(portDirections).length > 0 ? portDirections : undefined,
+ })
}
const addPort = () => {
@@ -36,88 +54,106 @@ export function Inspector({ document, selectedNode, issues, onUpdateDocument, on
onUpdateNode(selectedNode.id, { ports: { ...selectedNode.data.ports, [key]: '' } })
}
+ const getPortDir = (key: string): PortDirection | '' => {
+ if (!selectedNode?.data.portDirections) return ''
+ return selectedNode.data.portDirections[key] || ''
+ }
+
return (