diff --git a/webui/src/features/docs/DocsPage.tsx b/webui/src/features/docs/DocsPage.tsx index b94288c..a9893ee 100644 --- a/webui/src/features/docs/DocsPage.tsx +++ b/webui/src/features/docs/DocsPage.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { Link, useLocation } from "react-router-dom"; import { ChevronDown, ChevronRight, RefreshCw } from "lucide-react"; import { @@ -67,20 +67,29 @@ export default function DocsPage({ settings }: { settings: ApiSettings }) { const [context, setContext] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); + const loadSequence = useRef(0); const [documentationType, setDocumentationType] = useState(() => documentationTypeFromSearch(location.search)); const [expandedNodes, setExpandedNodes] = useState>(() => new Set()); const locale = localeFromSearch(location.search) ?? language; const adminDocs = documentationType === "admin"; async function load() { + const sequence = ++loadSequence.current; setLoading(true); setError(""); + setContext(null); try { - setContext(await fetchDocsContext(settings, { documentationType, locale })); + const nextContext = await fetchDocsContext(settings, { documentationType, locale }); + if (sequence !== loadSequence.current) return; + if (nextContext.actor.documentation_type !== documentationType) { + throw new Error("Documentation response type did not match the requested projection."); + } + setContext(nextContext); } catch (err) { + if (sequence !== loadSequence.current) return; setError(adminErrorMessage(err)); } finally { - setLoading(false); + if (sequence === loadSequence.current) setLoading(false); } }