File size: 2,210 Bytes
3193174
 
 
 
 
 
 
 
5cdde73
81f5c1c
5cdde73
 
 
3193174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5cdde73
 
 
 
 
 
 
 
 
3193174
 
 
 
 
 
 
 
5cdde73
3193174
5cdde73
 
3193174
 
 
5cdde73
3193174
 
 
 
 
 
 
5cdde73
3193174
5cdde73
 
 
 
 
 
 
 
 
 
3193174
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import {
  BaseEdge,
  EdgeLabelRenderer,
  getBezierPath,
  type EdgeProps,
} from "@xyflow/react";
import type { EdgeData } from "@/stores/graphStore";

function conditionLabel(condition: string): string {
  if (condition.startsWith("contains:")) return `kw: ${condition.slice(9)}`;
  return condition;
}

export function ConditionalEdge({
  id,
  sourceX,
  sourceY,
  targetX,
  targetY,
  sourcePosition,
  targetPosition,
  style = {},
  markerEnd,
  data,
}: EdgeProps) {
  const edgeData = data as unknown as EdgeData | undefined;
  const [edgePath, labelX, labelY] = getBezierPath({
    sourceX,
    sourceY,
    sourcePosition,
    targetX,
    targetY,
    targetPosition,
  });

  const condition = edgeData?.condition;
  const evaluated = edgeData?.evaluated;
  const weight = edgeData?.weight ?? 1.0;

  // Dim low-weight edges
  const opacity = weight < 0.3 ? 0.4 : weight < 0.6 ? 0.7 : 1;

  const strokeColor =
    evaluated === true ? "#22c55e" : evaluated === false ? "#94a3b8" : "#6366f1";

  const hasLabel = condition || weight < 1.0;

  return (
    <>
      <BaseEdge
        path={edgePath}
        markerEnd={markerEnd}
        style={{
          ...style,
          stroke: strokeColor,
          strokeWidth: 2,
          opacity,
          strokeDasharray: condition ? "6 3" : undefined,
        }}
        id={id}
      />
      {hasLabel && (
        <EdgeLabelRenderer>
          <div
            style={{
              position: "absolute",
              transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
              pointerEvents: "all",
            }}
            className="flex items-center gap-1 rounded border bg-background px-1.5 py-0.5 text-[10px] font-medium shadow-sm cursor-pointer hover:bg-accent"
          >
            {condition && (
              <span className="text-indigo-600 dark:text-indigo-400">
                {conditionLabel(condition)}
              </span>
            )}
            {weight < 1.0 && (
              <span className="text-muted-foreground">
                {condition ? " " : ""}w:{weight.toFixed(2)}
              </span>
            )}
          </div>
        </EdgeLabelRenderer>
      )}
    </>
  );
}