diff --git a/apps/web/src/components/topology/edge-edit-sheet.tsx b/apps/web/src/components/topology/edge-edit-sheet.tsx new file mode 100644 index 0000000..9c8f14a --- /dev/null +++ b/apps/web/src/components/topology/edge-edit-sheet.tsx @@ -0,0 +1,145 @@ +import { useEffect, useState } from 'react' +import { Input } from '@cfdm/ui/components/input' +import { Textarea } from '@cfdm/ui/components/textarea' +import { FormSheet } from '@/components/form-sheet' +import { FormField } from '@/components/form-field' +import { SelectField } from '@/components/select-field' +import { + EDGE_DIRECTION_OPTIONS, + EDGE_RELATION_OPTIONS, + defaultEdgeData, + type TopologyEdgeData, + type TopologyEdgeDirection, + type TopologyEdgeRelation, +} from './types' + +interface EdgeEditSheetProps { + edgeId: string | null + data: TopologyEdgeData | null + open: boolean + locked?: boolean + onOpenChange: (open: boolean) => void + onSave: (edgeId: string, data: TopologyEdgeData) => void +} + +export function EdgeEditSheet({ + edgeId, + data, + open, + locked, + onOpenChange, + onSave, +}: EdgeEditSheetProps) { + const [relation, setRelation] = useState('network') + const [label, setLabel] = useState('') + const [lineStyle, setLineStyle] = useState<'solid' | 'dashed'>('solid') + const [direction, setDirection] = useState('forward') + const [protocol, setProtocol] = useState('') + const [notes, setNotes] = useState('') + + useEffect(() => { + const d = data ?? defaultEdgeData() + setRelation(d.relation ?? 'network') + setLabel(d.label ?? '') + setLineStyle(d.lineStyle ?? 'solid') + setDirection(d.direction ?? 'forward') + setProtocol(d.protocol ?? '') + setNotes(d.notes ?? '') + }, [data, edgeId, open]) + + return ( + { + if (!edgeId || locked) return + onSave(edgeId, { + relation, + label: label.trim(), + lineStyle, + direction, + protocol: protocol.trim(), + notes: notes.trim(), + }) + onOpenChange(false) + }} + > + + { + if (v && EDGE_RELATION_OPTIONS.some((o) => o.value === v)) { + setRelation(v as TopologyEdgeRelation) + } + }} + options={EDGE_RELATION_OPTIONS} + disabled={locked} + /> + + + setLabel(e.target.value)} + disabled={locked} + maxLength={60} + placeholder="Например: eth0 / 10 Gbit" + /> + + + { + if (v === 'forward' || v === 'bidirectional' || v === 'none') setDirection(v) + }} + options={EDGE_DIRECTION_OPTIONS} + disabled={locked} + /> + + + { + if (v === 'solid' || v === 'dashed') setLineStyle(v) + }} + options={[ + { value: 'solid', label: 'Сплошная' }, + { value: 'dashed', label: 'Пунктир' }, + ]} + disabled={locked} + /> + + + setProtocol(e.target.value)} + disabled={locked} + maxLength={40} + placeholder="TCP/443, WireGuard, BGP…" + /> + + +