import { BaseEdge, EdgeLabelRenderer, getBezierPath, getSmoothStepPath, useStore, type EdgeProps, type Edge, } from '@xyflow/react' import type { EdgeData, EdgeType } from '@/types' import { useThemeStore } from '@/stores/themeStore' import { THEMES } from '@/utils/themes' const VLAN_COLORS = ['#00d4ff', '#a855f7', '#39d353', '#ff6e00', '#e3b341', '#f85149'] function getVlanColor(vlanId?: number): string { if (!vlanId) return '#00d4ff' return VLAN_COLORS[vlanId % VLAN_COLORS.length] } export function HomelableEdge({ id, source, target, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, selected }: EdgeProps>) { const activeTheme = useThemeStore((s) => s.activeTheme) const theme = THEMES[activeTheme] const sourceType = useStore((s) => s.nodeLookup.get(source)?.type) const targetType = useStore((s) => s.nodeLookup.get(target)?.type) const isBidirectional = sourceType === 'proxmox' && targetType === 'proxmox' const pathArgs = { sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition } const [edgePath, labelX, labelY] = data?.path_style === 'smooth' ? getSmoothStepPath({ ...pathArgs, borderRadius: 8 }) : getBezierPath(pathArgs) const edgeType: EdgeType = data?.type ?? 'ethernet' const edgeColors = theme.colors.edgeColors const BASE_STYLES: Record = { ethernet: { stroke: edgeColors.ethernet, strokeWidth: 2 }, wifi: { stroke: edgeColors.wifi, strokeWidth: 1.5, strokeDasharray: '6 3' }, iot: { stroke: edgeColors.iot, strokeWidth: 1.5, strokeDasharray: '2 4' }, vlan: { strokeWidth: 2.5 }, virtual: { stroke: edgeColors.virtual, strokeWidth: 1, strokeDasharray: '4 4' }, cluster: { stroke: edgeColors.cluster, strokeWidth: 2.5, strokeDasharray: '8 3' }, } const customColor = data?.custom_color as string | undefined const style: React.CSSProperties = { ...BASE_STYLES[edgeType], ...(edgeType === 'vlan' ? { stroke: getVlanColor(data?.vlan_id as number | undefined) } : {}), ...(customColor ? { stroke: customColor } : {}), ...(selected ? { stroke: theme.colors.edgeSelectedColor, filter: `drop-shadow(0 0 4px ${theme.colors.edgeSelectedColor}88)` } : {}), } // Normalize animated value — supports legacy boolean (true → 'snake') const animMode: 'none' | 'snake' | 'flow' = data?.animated === true || data?.animated === 'snake' ? 'snake' : data?.animated === 'flow' ? 'flow' : 'none' const animColor = customColor ?? (edgeType === 'vlan' ? getVlanColor(data?.vlan_id as number | undefined) : edgeColors[edgeType as keyof typeof edgeColors] as string) return ( <> {animMode === 'snake' && ( {isBidirectional ? ( ) : ( )} )} {animMode === 'flow' && ( )} {data?.label && (
{data.label as string}
)} ) }