import type { ReactNode } from "react"; import { FolderOpen } from "lucide-react"; import { Debug as DebugSvc } from "@bindings/services"; import type { DebugBundleResult } from "@bindings/services/models.js"; import { Button } from "@/components/Button"; import FancyToggleSwitch from "@/components/FancyToggleSwitch"; import HelpText from "@/components/HelpText.tsx"; import { Input } from "@/components/Input"; import { Label } from "@/components/Label"; import { StatusPanel } from "@/components/StatusPanel"; import { cn } from "@/lib/cn"; import type { DebugStage } from "@/modules/debug-bundle/useDebugBundle.ts"; import { useDebugBundleContext } from "@/modules/debug-bundle/useDebugBundleContext.ts"; import { SectionGroup } from "@/modules/settings/SettingsSection.tsx"; export function SettingsTroubleshooting() { const { anonymize, setAnonymize, systemInfo, setSystemInfo, upload, setUpload, trace, setTrace, traceMinutes, setTraceMinutes, run, stage, cancel, reset, } = useDebugBundleContext(); if (stage.kind === "done") { return ( ); } if (stage.kind !== "idle") { return ; } return ( A debug bundle helps NetBird support investigate connection problems.
It's a .zip file with logs, system details and debug information from your device.
How long to capture trace logs before generating the bundle.
setTraceMinutes(Math.max(1, Math.min(30, Number(e.target.value) || 1))) } customSuffix={"Minute(s)"} disabled={!trace} />
); } function ProgressSection({ stage, onCancel }: { stage: DebugStage; onCancel: () => void }) { const cancelling = stage.kind === "cancelling"; return ( {cancelling ? "Cancelling…" : "Cancel"} } /> ); } function DoneResult({ result, uploaded, onClose, }: { result: DebugBundleResult; uploaded: boolean; onClose: () => void; }) { const showKey = uploaded && Boolean(result.uploadedKey); const uploadFailed = uploaded && !result.uploadedKey; const onRevealPath = () => { if (!result.path) return; void DebugSvc.RevealFile(result.path).catch(() => {}); }; return ( {showKey ? ( ) : ( result.path && ( ) )} } >
{showKey && } {result.path && !showKey && ( } /> )} {uploadFailed && (
Upload failed {result.uploadFailureReason ? `: ${result.uploadFailureReason}` : "."} The bundle is still saved locally.
)}
); } function BottomBar({ children }: { children: ReactNode }) { return (
{children}
); } const stageLabel = (stage: DebugStage): string => { switch (stage.kind) { case "preparing-trace": return "Switching to trace logging…"; case "reconnecting": return "Reconnecting NetBird…"; case "capturing": { const fmt = (s: number) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`; return `Capturing logs — ${fmt( stage.totalSec - stage.remainingSec, )} / ${fmt(stage.totalSec)}`; } case "restoring-level": return "Restoring previous log level…"; case "bundling": return "Generating debug bundle…"; case "uploading": return "Uploading to NetBird…"; case "cancelling": return "Cancelling…"; default: return ""; } };