All files / utils layout.ts

100% Statements 14/14
100% Branches 6/6
100% Functions 9/9
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103            182x                         252x               1981x         1981x       7x                                                                       115x                         57x   107x 57x                       57x    
import { type Node, type Edge, MarkerType, Position } from "@xyflow/react";
import { majorConcepts, prereqEdgeData } from "../data/conceptGraph";
 
export function buildLegacyGraphElements(
  positions: Record<string, { x: number; y: number }>,
): { nodes: Node[]; edges: Edge[] } {
  const nodes: Node[] = majorConcepts.map((concept) => ({
    id: concept.name,
    type: "major",
    position: positions[concept.name] ?? { x: 0, y: 0 },
    data: {
      label: concept.label,
      color: concept.color,
      subconcepts: concept.subconcepts,
    },
    sourcePosition: Position.Top,
    targetPosition: Position.Bottom,
  }));
 
  const edges: Edge[] = prereqEdgeData.map((e) => ({
    id: `prereq-${e.source}-${e.target}`,
    source: e.source,
    target: e.target,
    sourceHandle: "top",
    targetHandle: "bottom",
    type: "default",
    style: {
      stroke: majorConcepts.find((c) => c.name === e.source)?.color,
      strokeWidth: 4,
    },
    markerEnd: {
      type: MarkerType.ArrowClosed,
      color: majorConcepts.find((c) => c.name === e.source)?.color,
    },
  }));
 
  return { nodes, edges };
}
 
export interface SubconceptLike {
  id: number;
  parentId: number;
  labelHtml: string;
}
 
export interface MajorConceptLike {
  id: number;
  labelHtml: string;
  color: string;
  subconcepts: SubconceptLike[];
}
 
export interface EdgeLike {
  id: number;
  sourceId: number;
  targetId: number;
  // Set (bright red) when the edge is part of a prerequisite cycle; null otherwise,
  // in which case the edge takes its source concept's color.
  color?: string | null;
}
 
// Same shape as buildLegacyGraphElements, but fully parameterized so it can build a
// graph from database-fetched data instead of the hardcoded conceptGraph.ts
// imports, using numeric concept ids (as strings) for React Flow node ids. Kept
// separate (rather than changing buildLegacyGraphElements itself) so the original,
// hardcoded-data code path used by LegacyHomePage.tsx / ConceptGraph.tsx is
// completely untouched.
export function buildScaffoldGraphElements(
  positions: Record<string, { x: number; y: number }>,
  majorConceptsData: MajorConceptLike[],
  prereqEdgeDataArg: EdgeLike[],
): { nodes: Node[]; edges: Edge[] } {
  const nodes: Node[] = majorConceptsData.map((concept) => ({
    id: String(concept.id),
    type: "major",
    position: positions[String(concept.id)] ?? { x: 0, y: 0 },
    data: {
      labelHtml: concept.labelHtml,
      color: concept.color,
      subconcepts: concept.subconcepts,
    },
    sourcePosition: Position.Top,
    targetPosition: Position.Bottom,
  }));
 
  const edges: Edge[] = prereqEdgeDataArg.map((e) => {
    const color =
      e.color ?? majorConceptsData.find((c) => c.id === e.sourceId)?.color;
    return {
      id: `prereq-${e.id}`,
      source: String(e.sourceId),
      target: String(e.targetId),
      sourceHandle: "top",
      targetHandle: "bottom",
      type: "default",
      style: { stroke: color, strokeWidth: 4 },
      markerEnd: { type: MarkerType.ArrowClosed, color },
    };
  });
 
  return { nodes, edges };
}