fix(rack-planner): compute port data synchronously in PortConfigModal to prevent empty first render
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, type FormEvent } from 'react';
|
||||
import { useState, useEffect, useMemo, type FormEvent } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import type { Port, Vlan, VlanMode } from '../../types';
|
||||
import { Modal } from '../ui/Modal';
|
||||
@@ -14,42 +14,45 @@ interface PortConfigModalProps {
|
||||
}
|
||||
|
||||
export function PortConfigModal({ portId, open, onClose }: PortConfigModalProps) {
|
||||
const { racks, fetchRacks } = useRackStore();
|
||||
const [port, setPort] = useState<Port | null>(null);
|
||||
const { racks, fetchRacks, deleteConnection } = useRackStore();
|
||||
const [vlans, setVlans] = useState<Vlan[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [fetching, setFetching] = useState(false);
|
||||
|
||||
// Synchronously find the port from the global store
|
||||
const port = useMemo(() => {
|
||||
for (const rack of racks) {
|
||||
for (const mod of rack.modules) {
|
||||
const found = mod.ports.find((p) => p.id === portId);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, [racks, portId]);
|
||||
|
||||
// Form state
|
||||
const [label, setLabel] = useState('');
|
||||
const [mode, setMode] = useState<VlanMode>('ACCESS');
|
||||
const [nativeVlanId, setNativeVlanId] = useState<string>('');
|
||||
const [taggedVlanIds, setTaggedVlanIds] = useState<string[]>([]);
|
||||
const [notes, setNotes] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [fetching, setFetching] = useState(false);
|
||||
|
||||
// Quick-create VLAN
|
||||
const [newVlanId, setNewVlanId] = useState('');
|
||||
const [newVlanName, setNewVlanName] = useState('');
|
||||
const [newVlanColor, setNewVlanColor] = useState('#3b82f6');
|
||||
const [creatingVlan, setCreatingVlan] = useState(false);
|
||||
|
||||
// Find the port from store
|
||||
// Reset form state when port is found or changed
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
let found: Port | undefined;
|
||||
for (const rack of racks) {
|
||||
for (const mod of rack.modules) {
|
||||
found = mod.ports.find((p) => p.id === portId);
|
||||
if (found) break;
|
||||
}
|
||||
if (found) break;
|
||||
if (port && open) {
|
||||
setLabel(port.label ?? '');
|
||||
setMode(port.mode);
|
||||
setNativeVlanId(port.nativeVlan?.toString() ?? '');
|
||||
setTaggedVlanIds(port.vlans.filter((v) => v.tagged).map((v) => v.vlanId));
|
||||
setNotes(port.notes ?? '');
|
||||
}
|
||||
if (found) {
|
||||
setPort(found);
|
||||
setLabel(found.label ?? '');
|
||||
setMode(found.mode);
|
||||
setNativeVlanId(found.nativeVlan?.toString() ?? '');
|
||||
setTaggedVlanIds(found.vlans.filter((v) => v.tagged).map((v) => v.vlanId));
|
||||
setNotes(found.notes ?? '');
|
||||
}
|
||||
}, [open, portId, racks]);
|
||||
}, [port, open]);
|
||||
|
||||
// Load VLAN list
|
||||
useEffect(() => {
|
||||
@@ -125,7 +128,6 @@ export function PortConfigModal({ portId, open, onClose }: PortConfigModalProps)
|
||||
|
||||
if (!port) return null;
|
||||
|
||||
const { deleteConnection } = useRackStore();
|
||||
const connections = [...(port.sourceConnections || []), ...(port.targetConnections || [])];
|
||||
|
||||
async function handleDisconnect(connId: string) {
|
||||
|
||||
Reference in New Issue
Block a user