import type { DragEvent, MouseEvent as ReactMouseEvent, RefObject } from 'react'; import type { AliasNode, ProviderNode, SourceNode } from './ModelMappingDiagramTypes'; import styles from './ModelMappingDiagram.module.scss'; interface ProviderColumnProps { providerNodes: ProviderNode[]; collapsedProviders: Set; getProviderColor: (provider: string) => string; providerGroupHeights?: Record; providerRefs: RefObject>; onToggleCollapse: (provider: string) => void; onContextMenu: (e: ReactMouseEvent, type: 'provider' | 'background', data?: string) => void; label: string; expandLabel: string; collapseLabel: string; } export function ProviderColumn({ providerNodes, collapsedProviders, getProviderColor, providerGroupHeights = {}, providerRefs, onToggleCollapse, onContextMenu, label, expandLabel, collapseLabel }: ProviderColumnProps) { return (
{ e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'background'); }} >
{label}
{providerNodes.map(({ provider, sources }) => { const collapsed = collapsedProviders.has(provider); const groupHeight = collapsed ? undefined : providerGroupHeights[provider]; return (
{ if (el) providerRefs.current?.set(provider, el); else providerRefs.current?.delete(provider); }} className={`${styles.item} ${styles.providerItem}`} style={{ borderLeftColor: getProviderColor(provider) }} onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'provider', provider); }} > {provider} {sources.length}
); })}
); } interface SourceColumnProps { providerNodes: ProviderNode[]; collapsedProviders: Set; sourceRefs: RefObject>; getProviderColor: (provider: string) => string; draggedSource: SourceNode | null; dropTargetSource: string | null; draggable: boolean; onDragStart: (e: DragEvent, source: SourceNode) => void; onDragEnd: () => void; onDragOver: (e: DragEvent, source: SourceNode) => void; onDragLeave: () => void; onDrop: (e: DragEvent, source: SourceNode) => void; onContextMenu: (e: ReactMouseEvent, type: 'source' | 'background', data?: string) => void; label: string; } export function SourceColumn({ providerNodes, collapsedProviders, sourceRefs, getProviderColor, draggedSource, dropTargetSource, draggable, onDragStart, onDragEnd, onDragOver, onDragLeave, onDrop, onContextMenu, label }: SourceColumnProps) { return (
{ e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'background'); }} >
{label}
{providerNodes.flatMap(({ provider, sources }) => { if (collapsedProviders.has(provider)) return []; return sources.map((source) => (
{ if (el) sourceRefs.current?.set(source.id, el); else sourceRefs.current?.delete(source.id); }} className={`${styles.item} ${styles.sourceItem} ${ draggedSource?.id === source.id ? styles.dragging : '' } ${dropTargetSource === source.id ? styles.dropTarget : ''}`} draggable={draggable} onDragStart={(e) => onDragStart(e, source)} onDragEnd={onDragEnd} onDragOver={(e) => onDragOver(e, source)} onDragLeave={onDragLeave} onDrop={(e) => onDrop(e, source)} onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'source', source.id); }} > {source.name}
0 ? 1 : 0.3 }} />
)); })}
); } interface AliasColumnProps { aliasNodes: AliasNode[]; aliasRefs: RefObject>; dropTargetAlias: string | null; draggedAlias: string | null; draggable: boolean; onDragStart: (e: DragEvent, alias: string) => void; onDragEnd: () => void; onDragOver: (e: DragEvent, alias: string) => void; onDragLeave: () => void; onDrop: (e: DragEvent, alias: string) => void; onContextMenu: (e: ReactMouseEvent, type: 'alias' | 'background', data?: string) => void; label: string; } export function AliasColumn({ aliasNodes, aliasRefs, dropTargetAlias, draggedAlias, draggable, onDragStart, onDragEnd, onDragOver, onDragLeave, onDrop, onContextMenu, label }: AliasColumnProps) { return (
{ e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'background'); }} >
{label}
{aliasNodes.map((node) => (
{ if (el) aliasRefs.current?.set(node.id, el); else aliasRefs.current?.delete(node.id); }} className={`${styles.item} ${styles.aliasItem} ${ dropTargetAlias === node.alias ? styles.dropTarget : '' } ${draggedAlias === node.alias ? styles.dragging : ''}`} draggable={draggable} onDragStart={(e) => onDragStart(e, node.alias)} onDragEnd={onDragEnd} onDragOver={(e) => onDragOver(e, node.alias)} onDragLeave={onDragLeave} onDrop={(e) => onDrop(e, node.alias)} onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); onContextMenu(e, 'alias', node.alias); }} >
{node.alias} {node.sources.length}
))}
); }