'use client' import { useState } from 'react' import { Button } from '../ui/button' import { Input } from '../ui/input' import { Label } from '../ui/label' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from '../ui/select' import { notify as defaultNotify } from '../toast' import { cn } from '../../lib/utils' import { suggestRelationshipKey, type SchemaId } from './schema-builder-core' import type { SchemaTypeBuilderNotifier } from './SchemaTypeBuilder' /** A type option the edge can connect (id + its key/label for display). */ export interface RelationshipTypeOption { id: SchemaId key: string label: string } export interface RelationshipBuilderClassNames { root?: string card?: string submit?: string } export interface RelationshipBuilderProps { /** The org's entity types — the selectable endpoints of the edge. */ types: RelationshipTypeOption[] /** Persist a relationship definition (typed edge source_type -> target_type). */ createRelationship: (input: { key: string sourceType: SchemaId targetType: SchemaId }) => Promise /** Fired after the relationship def is created (refetch here). */ onCreated?: (created: { key: string }) => void notify?: SchemaTypeBuilderNotifier classNames?: RelationshipBuilderClassNames } /** * No-code relationship builder (768w.10.4 S5): connect two entity types with a * typed edge. The persistence layer is injected via `createRelationship`; the * consuming app supplies the type list + handles refetch in `onCreated`. */ export function RelationshipBuilder({ types, createRelationship, onCreated, notify = defaultNotify, classNames, }: RelationshipBuilderProps) { const [sourceId, setSourceId] = useState('') const [targetId, setTargetId] = useState('') const [keyOverride, setKeyOverride] = useState('') const [saving, setSaving] = useState(false) const sourceKey = types.find((t) => String(t.id) === sourceId)?.key ?? '' const targetKey = types.find((t) => String(t.id) === targetId)?.key ?? '' const effectiveKey = keyOverride.trim() || suggestRelationshipKey(sourceKey, targetKey) async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!sourceId || !targetId) { notify.error?.('Pick a source and a target type.') return } if (!effectiveKey) { notify.error?.('Give the relationship a name.') return } setSaving(true) try { await createRelationship({ key: effectiveKey, sourceType: sourceId, targetType: targetId }) notify.success?.(`Connected ${sourceKey} → ${targetKey}.`) onCreated?.({ key: effectiveKey }) setKeyOverride('') } catch (err) { notify.error?.(err instanceof Error ? err.message : 'Could not create the relationship.') } finally { setSaving(false) } } return (
Connect two types {types.length === 0 ? (

Create at least one entity type first, then connect them.

) : ( <>
setKeyOverride(e.target.value)} placeholder={effectiveKey || 'auto-generated from the two types'} />

Stable identifier for this edge. Defaults to{' '} {effectiveKey || '—'}.

)}
) }