From 7984573c81b0aa1b1fed028f3854926ae1e59ef2 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Fri, 21 Aug 2026 15:54:08 +0200 Subject: [PATCH] fix: resolve semantic documentation deep links --- src/govoplan_docs/backend/api/v1/routes.py | 17 ++++++++--------- .../features/docs/SemanticDocumentationPage.tsx | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/govoplan_docs/backend/api/v1/routes.py b/src/govoplan_docs/backend/api/v1/routes.py index 25a9b36..52e3914 100644 --- a/src/govoplan_docs/backend/api/v1/routes.py +++ b/src/govoplan_docs/backend/api/v1/routes.py @@ -1083,7 +1083,7 @@ def _semantic_documentation_topics( "route": route, "route_anchor": route_anchor, "help_contexts": [ - _semantic_help_context(entry), + _semantic_help_context(entry, route_anchor=route_anchor), ], }, ) @@ -1091,20 +1091,19 @@ def _semantic_documentation_topics( return tuple(topics) -def _semantic_help_context(entry: object) -> str: +def _semantic_help_context( + entry: object, + *, + route_anchor: object | None, +) -> str: values = [ "semantic", str(getattr(entry, "subject_module_id")), str(getattr(entry, "subject_kind")), str(getattr(entry, "subject_id")), ] - if getattr(entry, "anchor_kind", None) and getattr(entry, "anchor_id", None): - values.extend( - ( - str(getattr(entry, "anchor_kind")), - str(getattr(entry, "anchor_id")), - ) - ) + if route_anchor: + values.append(str(route_anchor)) return ".".join(values) diff --git a/webui/src/features/docs/SemanticDocumentationPage.tsx b/webui/src/features/docs/SemanticDocumentationPage.tsx index bc71f03..20409d2 100644 --- a/webui/src/features/docs/SemanticDocumentationPage.tsx +++ b/webui/src/features/docs/SemanticDocumentationPage.tsx @@ -83,7 +83,17 @@ export default function SemanticDocumentationPage({ settings }: { settings: ApiS setEntries(nextEntries); const requestedEntry = searchParams.get("entryId"); const entry = nextEntries.find((item) => item.id === requestedEntry) ?? selectedEntry; - if (entry) selectExisting(entry, nextSubjects); + if (entry) { + selectExisting(entry, nextSubjects); + } else { + const requestedSubject = nextSubjects.find((item) => ( + item.reference.module_id === searchParams.get("module") + && item.reference.subject_kind === searchParams.get("subjectKind") + && item.reference.subject_id === searchParams.get("subjectId") + && (item.route_anchor ?? "") === (searchParams.get("routeAnchor") ?? "") + )); + if (requestedSubject) selectNew(requestedSubject, nextEntries); + } } catch (reason) { setError(adminErrorMessage(reason)); } finally { @@ -155,8 +165,8 @@ export default function SemanticDocumentationPage({ settings }: { settings: ApiS setSearchParams({ entryId: entry.id, locale: entry.locale }, { replace: true }); } - function selectNew(subject: SemanticSubjectDescriptor) { - const existing = entries.find((entry) => entry.locale === locale && sameSubject(entry.subject, subject.reference)); + function selectNew(subject: SemanticSubjectDescriptor, availableEntries = entries) { + const existing = availableEntries.find((entry) => entry.locale === locale && sameSubject(entry.subject, subject.reference)); if (existing) { selectExisting(existing); return;