import { useState, useEffect } from 'react' import { Plus, Trash2, Settings, ChevronRight, ChevronDown } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { scanApi, type DeepScanConfig } from '@/api/client' import { toast } from 'sonner' interface ScanConfigModalProps { open: boolean onClose: () => void onScanNow: () => void } const DEEP_DEFAULTS: DeepScanConfig = { http_ranges: [], http_probe_enabled: false, verify_tls: false } export function ScanConfigModal({ open, onClose, onScanNow }: ScanConfigModalProps) { const [ranges, setRanges] = useState(['']) const [saving, setSaving] = useState(false) // Deep-scan section. Pre-filled from persisted defaults; edits here are a // per-scan override passed to trigger() — they do NOT change the saved defaults. const [deepOpen, setDeepOpen] = useState(false) const [deepDefaults, setDeepDefaults] = useState(DEEP_DEFAULTS) const [httpProbe, setHttpProbe] = useState(false) const [verifyTls, setVerifyTls] = useState(false) const [httpRangesText, setHttpRangesText] = useState('') useEffect(() => { if (!open) return scanApi.getConfig() .then((res) => { const d = res.data setRanges(d.ranges.length > 0 ? d.ranges : ['']) const deep: DeepScanConfig = { http_ranges: d.http_ranges ?? [], http_probe_enabled: d.http_probe_enabled ?? false, verify_tls: d.verify_tls ?? false, } setDeepDefaults(deep) setHttpProbe(deep.http_probe_enabled) setVerifyTls(deep.verify_tls) setHttpRangesText(deep.http_ranges.join(', ')) setDeepOpen(deep.http_probe_enabled || deep.http_ranges.length > 0) }) .catch(() => {/* use defaults */}) }, [open]) const parseHttpRanges = () => httpRangesText.split(',').map((r) => r.trim()).filter(Boolean) const handleScanNow = async () => { const cleaned = ranges.map((r) => r.trim()).filter(Boolean) if (cleaned.length === 0) { toast.error('Add at least one IP range'); return } setSaving(true) try { // Persist IP ranges; leave deep-scan defaults as configured in Options. await scanApi.saveConfig({ ranges: cleaned, ...deepDefaults }) // Per-scan deep-scan override from this dialog. await scanApi.trigger({ http_ranges: parseHttpRanges(), http_probe_enabled: httpProbe, verify_tls: verifyTls, }) onScanNow() onClose() } catch { toast.error('Failed to start scan') } finally { setSaving(false) } } return ( !v && onClose()}> Scan Configuration
{/* IP Ranges */}
{ranges.map((r, i) => (
{ const next = [...ranges] next[i] = e.target.value setRanges(next) }} placeholder="192.168.1.0/24" className="font-mono text-sm bg-[#0d1117] border-border" />
))}
{/* Deep Scan (opt-in) */}
{deepOpen && (

Scan extra ports and probe HTTP services to identify apps on custom ports. Overrides the saved defaults for this scan only.

setHttpRangesText(e.target.value)} placeholder="8000-8100, 9000-9100" className="font-mono text-sm bg-[#0d1117] border-border" />
)}

Status check interval can be configured in the sidebar Settings.

) }