Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172/** * Shared React Flow types used across goal-map and learner-map features. */
import type { Edge, Node } from "@/features/learner-map/lib/comparator";
/** * Context menu state for node interactions. * Used when clicking on a node to show edit/delete/connect options. */export type ContextMenuState = { nodeId: string; nodeType: "text" | "connector"; position: { x: number; y: number };} | null;
/** * Connection mode state for manual edge creation. * Active when user clicks "Connect To" or "Connect From" on a link node. */export type ConnectionModeState = { active: boolean; linkNodeId: string; direction: "to" | "from"; // "to" = link→concept, "from" = concept→link} | null;
/** * History snapshot for undo/redo functionality. */export interface HistorySnapshot { nodes: Node[]; edges: Edge[];}
/** * Validates if a connection between nodes is valid. * Rules: * - Connections must go through a connector (link) node * - text→connector or connector→text is valid * - text→text or connector→connector is invalid * - A node cannot connect to itself (same source and target node ID) */export function isValidConnection( sourceType: string | undefined, targetType: string | undefined, sourceId?: string, targetId?: string,): boolean { // A node cannot connect to itself if (sourceId && targetId && sourceId === targetId) return false; // If types are the same, connection is invalid (must go through connector) if (sourceType === targetType) return false; // One must be 'text' (concept) and one must be 'connector' (link) const types = [sourceType, targetType]; return types.includes("text") && types.includes("connector");}
/** * Checks if two nodes already have an edge between them (in either direction). */export function areNodesConnected( edges: readonly { source: string; target: string }[], nodeA: string, nodeB: string,): boolean { return edges.some( (e) => (e.source === nodeA && e.target === nodeB) || (e.source === nodeB && e.target === nodeA), );}