UNPKG

react-erd

Version:

An easy-to-use component for rendering Entity Relationship Diagrams in React

1 lines 30.6 kB
{"version":3,"sources":["../src/RelationshipDiagram.tsx"],"sourcesContent":["import {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport {\n Connection,\n Edge,\n Node,\n NodeProps,\n EdgeProps,\n useReactFlow,\n ReactFlowProvider,\n ReactFlow,\n Handle,\n Position,\n ConnectionLineType,\n getSmoothStepPath,\n} from \"reactflow\";\n\nimport { Icon } from \"@mdi/react\";\nimport { mdiKeyLink, mdiKey, mdiLinkVariant } from \"@mdi/js\";\n\nexport type DataType =\n | \"binary\"\n | \"number\"\n | \"boolean\"\n | \"text\"\n | \"datetime\"\n | \"hierarchical\"\n | \"geometric\"\n | \"money\"\n | \"other\";\n\ntype ForeignKey = {\n foreignSchemaName: string;\n foreignTableName: string;\n foreignColumnName: string;\n constrained: boolean;\n};\n\ntype DatabaseTableInfo = {\n name: string;\n primaryKey: string | string[];\n columns: {\n name: string;\n type: DataType;\n foreignKeys: ForeignKey[];\n }[];\n};\n\nexport type DatabaseSchemaInfo = {\n name: string;\n tables: DatabaseTableInfo[];\n};\n\nconst getRef = (schemaName: string, tableName: string, columnName?: string) =>\n [schemaName, tableName, columnName].filter((x) => x).join(\".\");\n\nconst getEdges = (schemas: DatabaseSchemaInfo[]): Edge[] =>\n schemas.flatMap((schema) => {\n return schema.tables.flatMap((table) =>\n table.columns.flatMap((column) => {\n return column.foreignKeys.map((foreignKey): Edge => {\n return {\n id: `${getRef(schema.name, table.name, column.name)}:${getRef(\n foreignKey.foreignSchemaName,\n foreignKey.foreignTableName,\n foreignKey.foreignColumnName\n )}`,\n source: getRef(schema.name, table.name),\n sourceHandle: column.name,\n target: getRef(\n foreignKey.foreignSchemaName,\n foreignKey.foreignTableName\n ),\n targetHandle: foreignKey.foreignColumnName,\n type: \"betweenTables\",\n deletable: !foreignKey.constrained,\n };\n });\n })\n );\n });\n\ntype TableWithSchemaName = DatabaseTableInfo & {\n schemaName: string;\n};\ntype TableNodeData = {\n id: string;\n table: TableWithSchemaName;\n foreignKeysReferencingTable: ForeignKey[];\n color: string;\n};\ntype TableNode = Node<TableNodeData>;\n\nconst X_MULTIPLIER = 350;\nconst Y_PADDING = 25;\nconst ROW_HEIGHT = 21;\nconst NODE_WIDTH = 250;\n\nexport type SpecifiedForeignKey = Omit<ForeignKey, \"constrained\"> & {\n localSchemaName: string;\n localTableName: string;\n localColumnName: string;\n};\n\nexport type RelationshipDiagramProps = {\n schemas: DatabaseSchemaInfo[];\n onSchemasChange?: (newSchemas: DatabaseSchemaInfo[]) => void;\n tableColors: string[];\n onCreateForeignKey?: (foreignKey: SpecifiedForeignKey) => void;\n onDeleteForeignKey?: (foreignKey: SpecifiedForeignKey) => void;\n onAttemptToRecreateExistingRelationship?: (\n attemptedForeignKey: SpecifiedForeignKey\n ) => void;\n onAttemptToConnectColumnToItself?: (column: {\n schemaName: string;\n tableName: string;\n columnName: string;\n }) => void;\n onAttemptToDeleteConstrainedRelationship?: (\n foreignKey: SpecifiedForeignKey\n ) => void;\n};\n\nfunction RelationshipDiagram({\n schemas,\n onSchemasChange,\n tableColors,\n onCreateForeignKey,\n onDeleteForeignKey,\n onAttemptToRecreateExistingRelationship,\n onAttemptToConnectColumnToItself,\n onAttemptToDeleteConstrainedRelationship,\n}: RelationshipDiagramProps) {\n const reactFlowInstance = useReactFlow();\n\n const schemasRef = useRef(schemas);\n useEffect(() => {\n schemasRef.current = schemas;\n }, [schemas]);\n\n const defaultEdges = useMemo(() => getEdges(schemas), [schemas]);\n\n const [isCreatingNewConnection, setIsCreatingNewConnection] = useState(false);\n\n const TableNodeComponent = useMemo(\n () =>\n function TableNodeComponent({\n data: { table, color },\n }: NodeProps<TableNodeData>) {\n return (\n <div style={{ width: NODE_WIDTH }}>\n <div className=\"title\" style={{ borderTopColor: color }}>\n {table.name}\n </div>\n <ul>\n {table.columns.map((column) => (\n <li key={column.name}>\n {(() => {\n const foreignKey =\n column.foreignKeys.filter((key) => key.constrained)\n .length >= 1;\n const isPrimary = table.primaryKey === column.name;\n if (foreignKey && isPrimary) {\n return <Icon path={mdiKeyLink} className=\"column-icon\" />;\n } else if (foreignKey) {\n return (\n <Icon path={mdiLinkVariant} className=\"column-icon\" />\n );\n } else if (isPrimary) {\n return <Icon path={mdiKey} className=\"column-icon\" />;\n } else {\n return <div className=\"column-icon\" />;\n }\n })()}\n <div className=\"column-name\">{column.name}</div>\n <div className=\"column-type\">{column.type}</div>\n </li>\n ))}\n </ul>\n {table.columns.map((column, index) => {\n const top = ROW_HEIGHT * 1.5 + index * ROW_HEIGHT + 5;\n return (\n <Fragment key={column.name}>\n <Handle\n id={column.name}\n type=\"source\"\n position={Position.Left}\n style={{\n top,\n transform: `translate(5px, -50%)`,\n pointerEvents: isCreatingNewConnection ? \"none\" : \"all\",\n }}\n />\n <Handle\n id={column.name}\n type=\"target\"\n position={Position.Right}\n style={{\n top,\n transform: `translate(-4px, -50%)`,\n pointerEvents: isCreatingNewConnection ? \"all\" : \"none\",\n }}\n />\n </Fragment>\n );\n })}\n </div>\n );\n },\n [isCreatingNewConnection]\n );\n\n const nodeTypes = useMemo(\n () => ({ table: TableNodeComponent }),\n [TableNodeComponent]\n );\n\n const BetweenTablesEdgeComponent = useMemo(\n () =>\n function BetweenTablesEdgeComponent(props: EdgeProps) {\n const { id, style = {} } = props;\n\n const [edgePath] = getSmoothStepPath(props);\n\n return (\n <>\n <path\n id={id}\n style={style}\n className=\"react-flow__edge-path\"\n d={edgePath}\n />\n <line\n x1={props.sourceX - 9}\n x2={props.sourceX}\n y1={props.sourceY}\n y2={props.sourceY - 6}\n style={style}\n strokeLinecap=\"round\"\n />\n <line\n x1={props.sourceX - 9}\n x2={props.sourceX}\n y1={props.sourceY}\n y2={props.sourceY + 6}\n style={style}\n strokeLinecap=\"round\"\n />\n <line\n x1={props.targetX + 10}\n x2={props.targetX + 10}\n y1={props.targetY - 8}\n y2={props.targetY + 8}\n style={style}\n strokeLinecap=\"round\"\n />\n </>\n );\n },\n []\n );\n\n const edgeTypes = useMemo(\n () => ({ betweenTables: BetweenTablesEdgeComponent }),\n [BetweenTablesEdgeComponent]\n );\n\n const defaultNodes = useMemo(() => {\n const nodes: TableNode[] = [];\n\n const allTables = schemas.flatMap((schema) =>\n schema.tables.map((table) => ({ ...table, schemaName: schema.name }))\n );\n\n const parentTables = allTables.filter((table) =>\n table.columns.every((column) => column.foreignKeys.length === 0)\n );\n\n let maxX = 0;\n function createNodesForTables(\n tables: TableWithSchemaName[],\n parentXPosition = 0,\n parentYBottom = 0\n ) {\n const xPosition = parentXPosition + X_MULTIPLIER;\n\n maxX = Math.max(xPosition, maxX);\n\n let prevTableMaxY = 0;\n for (const [index, table] of tables.entries()) {\n const id = getRef(table.schemaName, table.name);\n if (nodes.some((node) => node.data.id === id)) {\n continue;\n }\n nodes;\n const yPosition = Math.max(parentYBottom, prevTableMaxY);\n\n const foreignKeysReferencingTable = allTables.flatMap((table) =>\n table.columns.flatMap((column) =>\n column.foreignKeys.filter(\n (foreignKey) =>\n getRef(\n foreignKey.foreignSchemaName,\n foreignKey.foreignTableName\n ) === id\n )\n )\n );\n\n nodes.push({\n id: id,\n data: {\n id,\n table,\n foreignKeysReferencingTable,\n color: tableColors[nodes.length % tableColors.length],\n },\n position: {\n x: xPosition,\n y: yPosition,\n },\n sourcePosition: Position.Left,\n targetPosition: Position.Right,\n type: \"table\",\n });\n const nextTables = allTables.filter((table) =>\n table.columns.some((column) =>\n column.foreignKeys.some(\n (foreignKey) =>\n getRef(\n foreignKey.foreignSchemaName,\n foreignKey.foreignTableName\n ) === id\n )\n )\n );\n\n const maxYPositionOfChildren = createNodesForTables(\n nextTables,\n xPosition,\n yPosition\n );\n const nodeHeight = ROW_HEIGHT + table.columns.length * ROW_HEIGHT;\n if (index === tables.length - 1) {\n return yPosition + nodeHeight + Y_PADDING;\n } else {\n prevTableMaxY = Math.max(\n maxYPositionOfChildren ?? 0,\n yPosition + nodeHeight + Y_PADDING\n );\n }\n }\n }\n\n createNodesForTables(parentTables);\n\n return nodes;\n }, [schemas, tableColors]);\n\n const handleConnectionStart = useCallback(() => {\n setIsCreatingNewConnection(true);\n }, []);\n\n const handleConnectionEnd = useCallback(() => {\n setIsCreatingNewConnection(false);\n }, []);\n\n const handleAddConnectionBetweenNodes = useCallback(\n (connection: Connection) => {\n const [localSchemaName, localTableName] = connection.source!.split(\".\");\n if (\n defaultEdges.some(\n (edge) =>\n edge.id ===\n `${connection.source}.${connection.sourceHandle}:${connection.target}.${connection.targetHandle}`\n )\n ) {\n const [foreignSchemaName, foreignTableName] =\n connection.target!.split(\".\");\n onAttemptToRecreateExistingRelationship?.({\n localSchemaName,\n localTableName,\n localColumnName: connection.sourceHandle!,\n foreignSchemaName,\n foreignTableName,\n foreignColumnName: connection.targetHandle!,\n });\n return;\n }\n if (\n connection.target === connection.source &&\n connection.targetHandle === connection.sourceHandle\n ) {\n onAttemptToConnectColumnToItself?.({\n schemaName: localSchemaName,\n tableName: localTableName,\n columnName: connection.sourceHandle!,\n });\n return;\n }\n if (\n connection.target &&\n connection.targetHandle &&\n connection.source &&\n connection.sourceHandle\n ) {\n const [targetSchema, targetTable] = connection.target.split(\".\");\n const [sourceSchema, sourceTable] = connection.source.split(\".\");\n const newSchemas = schemasRef.current.map((schema) => ({\n ...schema,\n tables: schema.tables.map((table) => ({\n ...table,\n columns: table.columns.map((column) => {\n const ret = { ...column };\n if (\n connection.targetHandle &&\n sourceSchema === schema.name &&\n sourceTable === table.name &&\n connection.sourceHandle === column.name\n ) {\n ret.foreignKeys.push({\n foreignSchemaName: targetSchema,\n foreignTableName: targetTable,\n foreignColumnName: connection.targetHandle,\n constrained: false,\n });\n }\n return ret;\n }),\n })),\n }));\n onSchemasChange?.(newSchemas);\n onCreateForeignKey?.({\n localSchemaName: sourceSchema,\n localTableName: sourceTable,\n localColumnName: connection.sourceHandle,\n foreignSchemaName: targetSchema,\n foreignTableName: targetTable,\n foreignColumnName: connection.targetHandle,\n });\n }\n },\n [\n defaultEdges,\n onAttemptToRecreateExistingRelationship,\n onAttemptToConnectColumnToItself,\n onSchemasChange,\n onCreateForeignKey,\n ]\n );\n\n const newConnectionToCreateRef = useRef<Connection | null>(null);\n\n const handleEdgeUpdate = useCallback(\n (_: unknown, newConnection: Connection) => {\n newConnectionToCreateRef.current = newConnection;\n },\n []\n );\n\n const handleEdgeUpdateStart = useCallback(() => {\n newConnectionToCreateRef.current = null;\n }, []);\n\n const handleEdgeUpdateEnd = useCallback(\n (_: unknown, edgeToDelete: Edge) => {\n const onDeleteArg = (() => {\n const [sourceSchema, sourceTable] = edgeToDelete.source.split(\".\");\n const [targetSchema, targetTable] = edgeToDelete.target.split(\".\");\n return {\n localSchemaName: sourceSchema,\n localTableName: sourceTable,\n localColumnName: edgeToDelete.sourceHandle!,\n foreignSchemaName: targetSchema,\n foreignTableName: targetTable,\n foreignColumnName: edgeToDelete.targetHandle!,\n };\n })();\n if (!edgeToDelete.deletable) {\n onAttemptToDeleteConstrainedRelationship?.(onDeleteArg);\n }\n onDeleteForeignKey?.(onDeleteArg);\n if (newConnectionToCreateRef.current) {\n // this means the edge has been moved to a new handle - create a new foreign key\n const onCreateArg = (() => {\n const [sourceSchema, sourceTable] =\n newConnectionToCreateRef.current.source!.split(\".\");\n const [targetSchema, targetTable] =\n newConnectionToCreateRef.current.target!.split(\".\");\n return {\n localSchemaName: sourceSchema,\n localTableName: sourceTable,\n localColumnName: newConnectionToCreateRef.current.sourceHandle!,\n foreignSchemaName: targetSchema,\n foreignTableName: targetTable,\n foreignColumnName: newConnectionToCreateRef.current.targetHandle!,\n };\n })();\n onCreateForeignKey?.(onCreateArg);\n }\n const newSchemas = schemasRef.current.map((schema) => ({\n ...schema,\n tables: schema.tables.map((table) => ({\n ...table,\n columns: table.columns.map((column) => {\n const ret = { ...column };\n const matchesColumn = (edgeLike: Edge | Connection) =>\n edgeLike.source === getRef(schema.name, table.name) &&\n edgeLike.sourceHandle === column.name;\n if (matchesColumn(edgeToDelete)) {\n ret.foreignKeys = ret.foreignKeys.filter((foreignKey) => {\n const wasDeleted =\n getRef(\n foreignKey.foreignSchemaName,\n foreignKey.foreignTableName\n ) === edgeToDelete.target &&\n foreignKey.foreignColumnName === edgeToDelete.targetHandle;\n return !wasDeleted;\n });\n }\n if (\n newConnectionToCreateRef.current &&\n matchesColumn(newConnectionToCreateRef.current)\n ) {\n const [targetSchema, targetTable] =\n newConnectionToCreateRef.current.target!.split(\".\");\n ret.foreignKeys = [\n ...ret.foreignKeys,\n {\n foreignSchemaName: targetSchema,\n foreignTableName: targetTable,\n foreignColumnName:\n newConnectionToCreateRef.current.targetHandle!,\n constrained: false,\n },\n ];\n }\n return ret;\n }),\n })),\n }));\n onSchemasChange?.(newSchemas);\n },\n [\n onAttemptToDeleteConstrainedRelationship,\n onCreateForeignKey,\n onDeleteForeignKey,\n onSchemasChange,\n ]\n );\n\n const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null);\n const handleNodeMouseEnter = useCallback((_: unknown, node: Node) => {\n setHoveredNodeId(node.id);\n }, []);\n const handleNodeMouseLeave = useCallback(() => {\n setHoveredNodeId(null);\n }, []);\n\n useEffect(() => {\n const checkIfShouldHighlightEdge = (edge: Edge) =>\n hoveredNodeId && [edge.source, edge.target].includes(hoveredNodeId);\n reactFlowInstance.setEdges(\n [...defaultEdges]\n .sort(\n (a, b) =>\n Number(checkIfShouldHighlightEdge(a)) -\n Number(checkIfShouldHighlightEdge(b))\n )\n .map((edge) => {\n const shouldHighlight =\n hoveredNodeId && checkIfShouldHighlightEdge(edge);\n return {\n ...edge,\n style: {\n ...edge.style,\n zIndex: 500,\n stroke: shouldHighlight\n ? (defaultNodes ?? []).find((node) => node.id === edge.target)\n ?.data.color\n : \"rgb(var(--react-erd__secondary-color))\",\n strokeWidth: shouldHighlight ? 2 : 1,\n transition: \"stroke 0.3s\",\n },\n };\n })\n );\n }, [defaultEdges, hoveredNodeId, defaultNodes, reactFlowInstance]);\n\n const ids = useRef(new WeakMap());\n const currId = useRef(0);\n const getObjectId = useCallback((object: object) => {\n if (ids.current.has(object)) {\n return ids.current.get(object);\n } else {\n const id = String(currId.current);\n currId.current += 1;\n ids.current.set(object, id);\n return id;\n }\n }, []);\n\n if (!defaultNodes) {\n return <div>Loading</div>;\n }\n\n return (\n <>\n <div\n className=\"react-erd__container\"\n style={\n { \"--row-height\": `${ROW_HEIGHT}px` } as {\n [x: string]: string;\n }\n }\n >\n <ReactFlow\n key={getObjectId(schemas)}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n defaultNodes={defaultNodes}\n defaultEdges={defaultEdges}\n fitView\n connectionRadius={30}\n connectionLineType={ConnectionLineType.SmoothStep}\n onNodeMouseEnter={handleNodeMouseEnter}\n onNodeMouseLeave={handleNodeMouseLeave}\n onEdgeUpdate={handleEdgeUpdate}\n onEdgeUpdateStart={handleEdgeUpdateStart}\n onEdgeUpdateEnd={handleEdgeUpdateEnd}\n onConnectStart={handleConnectionStart}\n onConnectEnd={handleConnectionEnd}\n onConnect={handleAddConnectionBetweenNodes}\n />\n </div>\n </>\n );\n}\n\nfunction RelationshipDiagramWrapper(props: RelationshipDiagramProps) {\n return (\n <ReactFlowProvider>\n <RelationshipDiagram {...props} />\n </ReactFlowProvider>\n );\n}\n\nexport { RelationshipDiagramWrapper as RelationshipDiagram };\n"],"mappings":"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","names":["import_react","TableNodeComponent","BetweenTablesEdgeComponent","table"]}