import { useEffect, useState, useRef } from "react"; import { Cardinality, tableColorStripHeight, tableFieldHeight, tableHeaderHeight, tableWidth, } from "../data/constants"; import { calcPath } from "../utils/calcPath"; function Table({ table, grab }) { const [isHovered, setIsHovered] = useState(false); const [hoveredField, setHoveredField] = useState(-1); const height = table.fields.length * tableFieldHeight + tableHeaderHeight + tableColorStripHeight; return ( { // Required for onPointerLeave to trigger when a touch pointer leaves // https://stackoverflow.com/a/70976017/1137077 e.target.releasePointerCapture(e.pointerId); if (!e.isPrimary) return; grab(e); }} onPointerEnter={(e) => e.isPrimary && setIsHovered(true)} onPointerLeave={(e) => e.isPrimary && setIsHovered(false)} >
{table.name}
{table.fields.map((e, i) => (
e.isPrimary && setHoveredField(i)} onPointerLeave={(e) => e.isPrimary && setHoveredField(-1)} onPointerDown={(e) => { // Required for onPointerLeave to trigger when a touch pointer leaves // https://stackoverflow.com/a/70976017/1137077 e.target.releasePointerCapture(e.pointerId); }} >
{e.type}
))}
); } function Relationship({ relationship, tables }) { const pathRef = useRef(); let start = { x: 0, y: 0 }; let end = { x: 0, y: 0 }; let cardinalityStart = "1"; let cardinalityEnd = "1"; switch (relationship.cardinality) { case Cardinality.MANY_TO_ONE: cardinalityStart = "n"; cardinalityEnd = "1"; break; case Cardinality.ONE_TO_MANY: cardinalityStart = "1"; cardinalityEnd = "n"; break; case Cardinality.ONE_TO_ONE: cardinalityStart = "1"; cardinalityEnd = "1"; break; default: break; } const length = 32; const [refAquired, setRefAquired] = useState(false); useEffect(() => { setRefAquired(true); }, []); if (refAquired) { const pathLength = pathRef.current.getTotalLength(); const point1 = pathRef.current.getPointAtLength(length); start = { x: point1.x, y: point1.y }; const point2 = pathRef.current.getPointAtLength(pathLength - length); end = { x: point2.x, y: point2.y }; } return ( console.log(pathRef.current)}> {pathRef.current && ( <> {cardinalityStart} {cardinalityEnd} )} ); } export default function SimpleCanvas({ diagram, zoom }) { const [tables, setTables] = useState(diagram.tables); const [dragging, setDragging] = useState(-1); const [offset, setOffset] = useState({ x: 0, y: 0 }); const grabTable = (e, id) => { setDragging(id); setOffset({ x: e.clientX - tables[id].x, y: e.clientY - tables[id].y, }); }; const moveTable = (e) => { if (dragging !== -1) { const dx = e.clientX - offset.x; const dy = e.clientY - offset.y; setTables((prev) => prev.map((table, i) => i === dragging ? { ...table, x: dx, y: dy } : table, ), ); } }; const releaseTable = () => { setDragging(-1); setOffset({ x: 0, y: 0 }); }; return ( e.isPrimary && releaseTable()} onPointerMove={(e) => e.isPrimary && moveTable()} onPointerLeave={(e) => e.isPrimary && releaseTable()} > {diagram.relationships.map((r, i) => ( ))} {tables.map((t, i) => ( grabTable(e, i)} /> ))} ); }