From 1a48724f161c591bcdc8164250fb3bacba8ff7b6 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Sun, 23 Aug 2026 19:31:21 +0200 Subject: [PATCH] docs(dashboard): complete German reference coverage --- package.json | 2 +- pyproject.toml | 3 +- src/govoplan_dashboard/__init__.py | 2 +- src/govoplan_dashboard/backend/manifest.py | 77 ++++++++++++++++++- .../test_interface_documentation_contract.py | 24 ++++++ webui/package.json | 2 +- 6 files changed, 104 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index aaa1dd0..841c772 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/dashboard-webui", - "version": "0.1.18", + "version": "0.1.19", "private": true, "type": "module", "main": "webui/src/index.ts", diff --git a/pyproject.toml b/pyproject.toml index 0b6919f..dd6c031 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-dashboard" -version = "0.1.18" +version = "0.1.19" description = "GovOPlaN configurable dashboard module." readme = "README.md" requires-python = ">=3.12" @@ -22,4 +22,3 @@ govoplan_dashboard = ["py.typed"] [project.entry-points."govoplan.modules"] dashboard = "govoplan_dashboard.backend.manifest:get_manifest" - diff --git a/src/govoplan_dashboard/__init__.py b/src/govoplan_dashboard/__init__.py index 1387663..a011fb9 100644 --- a/src/govoplan_dashboard/__init__.py +++ b/src/govoplan_dashboard/__init__.py @@ -2,4 +2,4 @@ __all__ = ["__version__"] -__version__ = "0.1.18" +__version__ = "0.1.19" diff --git a/src/govoplan_dashboard/backend/manifest.py b/src/govoplan_dashboard/backend/manifest.py index d585525..d7559a5 100644 --- a/src/govoplan_dashboard/backend/manifest.py +++ b/src/govoplan_dashboard/backend/manifest.py @@ -51,7 +51,7 @@ def _tenant_summary(session, tenant_id: str) -> dict[str, int]: manifest = ModuleManifest( id="dashboard", name="Dashboard", - version="0.1.18", + version="0.1.19", required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR), optional_dependencies=("ops", "campaigns", "files", "mail", "tasks", "notifications", "reporting"), provides_interfaces=( @@ -171,6 +171,7 @@ manifest = ModuleManifest( related_modules=("core", "views"), order=19, metadata={ + "kind": "reference", "help_contexts": [ "dashboard.page", "dashboard.action.reset", @@ -185,6 +186,31 @@ manifest = ModuleManifest( ), }, }, + translations={ + "de": { + "title": "Datenschutzanfragen zum Dashboard", + "summary": ( + "Persönliche Dashboard-Layouts ausgeben oder löschen, ohne die von Widgets dargestellten Daten zu verändern." + ), + "body": ( + "Dashboard trägt Layouts nur bei, wenn die Anfrage im aktiven Mandanten genau eine bestätigte " + "Kontokennung enthält. Ein Layout- oder View-Verweis kann das Ergebnis einschränken. Das Auskunftspaket " + "enthält Layoutversion, Revision, View, Widgetkennungen, Größen und Positionen. Beliebige Werte der " + "Widgetkonfiguration werden bewusst ausgelassen; einem Widget wird nie in sein Eigentümermodul gefolgt. " + "Die Löschung entfernt das ausgewählte kontoeigene Layout nach Prüfung von Eigentümer und Revision; eine " + "Wiederholung bleibt unverändert. Widgets, Berichte, Dateien, Tasks und andere Fachdaten werden nicht gelöscht." + ), + } + }, + structured_translation_version="1", + structured_translations={ + "de": { + "consequence_classes": { + "export_layout": "Gibt eine minimierte Layoutstruktur zurück, niemals Daten der Widget-Fachdomäne.", + "delete_layout": "Entfernt ausschließlich das ausgewählte persönliche Layout unwiderruflich.", + } + } + }, ), DocumentationTopic( id="dashboard.configurable-home", @@ -212,6 +238,21 @@ manifest = ModuleManifest( "dashboard.state.view-specific", ], }, + translations={ + "de": { + "title": "Konfigurierbares Benutzer-Dashboard", + "summary": ( + "Das Dashboard-Modul führt die konfigurierbare Startoberfläche; Fachmodule stellen Widgets über die enge Fähigkeit dashboard.widgets bereit." + ), + "body": ( + "Core stellt nur dann eine minimale Ersatzstartseite bereit, wenn das Dashboard-Modul fehlt. Dashboard-Widgets " + "müssen über Core-Verträge beigetragen werden und dürfen Komponenten anderer Module nicht direkt importieren. " + "Persönliche Layouts werden je Mandant, Konto und aktivem View gespeichert. Die Anzahl aktiver Oberflächenmodule " + "umfasst nur mandantenaktivierte Module, deren WebUI in der aktuellen Browsersitzung geladen wurde. Sie unterscheidet " + "sich bewusst vom Paketkatalog der Administration, der auch entdeckte reine Backend- und Headless-Manifeste enthält." + ), + } + }, ), DocumentationTopic( id="dashboard.reference.layout-and-widgets", @@ -237,6 +278,7 @@ manifest = ModuleManifest( related_modules=("core", "views", "access", "ops"), order=21, metadata={ + "kind": "reference", "help_contexts": [ "dashboard.action.configure", "dashboard.action.save", @@ -252,6 +294,39 @@ manifest = ModuleManifest( "configure_widget": "Changes presentation and query preferences for one widget placement.", }, }, + translations={ + "de": { + "title": "Dashboard-Layouts und Widgetfolgen", + "summary": ( + "Platzierung, Größe, Konfiguration, Verfügbarkeit und Rückfallverhalten von Widgets je Benutzer, Mandant und View." + ), + "body": ( + "Ein Dashboard-Layout gehört zum aktiven Mandanten, Konto und fokussierten View. Konfigurationen ändern " + "zunächst nur einen lokalen Entwurf; erst Layout speichern übernimmt sie. Abbrechen oder Verwerfen stellt " + "die zuletzt gespeicherte Anordnung wieder her. Die Seitenaktionsleiste zeigt stets, ob der Entwurf gespeichert, " + "ungespeichert oder in Speicherung ist; Speichern und Abbrechen bleiben an stabilen Positionen und sind mit " + "Erklärung deaktiviert, wenn keine Änderung vorliegt. Beim Verlassen eines geänderten Entwurfs greift die gemeinsame " + "Speichern-oder-Verwerfen-Sicherung. Das Entfernen eines Widgets entfernt nur seine Platzierung, nicht die dargestellten " + "Moduldaten. Zurücksetzen übernimmt die von aktuell aktiven Modulen angekündigten Standardwerte und bleibt bis zum " + "Speichern umkehrbar. Ein Widget wird nur angeboten, wenn Modul, fokussierte View-Oberfläche und Berechtigungsvertrag " + "verfügbar sind. Widgets gewähren keinen Zugriff; Anbieter müssen jede Datenanfrage autorisieren. Ist das Serverlayout " + "nicht erreichbar, kann ein Browser- oder Modulstandard angezeigt werden, bleibt aber bis zum Speichern als Rückfall " + "gekennzeichnet. Gleichzeitige Speicherungen verwenden die Layoutrevision und weisen veraltete Änderungen zurück, " + "statt sie zu überschreiben." + ), + } + }, + structured_translation_version="1", + structured_translations={ + "de": { + "consequence_classes": { + "save_layout": "Speichert das vollständige Layout im Revisionskontext von aktivem Mandant, Konto und View.", + "reset_layout": "Ersetzt den Entwurf durch aktuelle Modulstandardwerte und bleibt bis zum Speichern umkehrbar.", + "remove_widget": "Entfernt nur die Platzierung aus dem Entwurf; Anbieterdaten bleiben unverändert.", + "configure_widget": "Ändert Darstellungs- und Abfrageeinstellungen einer Widgetplatzierung.", + } + } + }, ), ), architecture=declared_module_architecture( diff --git a/tests/test_interface_documentation_contract.py b/tests/test_interface_documentation_contract.py index 8f7f27f..7a7839f 100644 --- a/tests/test_interface_documentation_contract.py +++ b/tests/test_interface_documentation_contract.py @@ -3,6 +3,10 @@ from __future__ import annotations from pathlib import Path import unittest +from govoplan_core.core.modules import ( + documentation_structured_translation_issues, + localizable_documentation_metadata_keys, +) from govoplan_dashboard.backend.manifest import get_manifest @@ -39,6 +43,26 @@ class DashboardInterfaceDocumentationContractTests(unittest.TestCase): self.assertIn("save_layout", reference.metadata["consequence_classes"]) self.assertIn("remove_widget", reference.metadata["consequence_classes"]) + def test_german_reference_documentation_is_complete(self) -> None: + topics = get_manifest().documentation + self.assertEqual(3, len(topics)) + for topic in topics: + translation = topic.translations.get("de", {}) + self.assertTrue(translation.get("title"), topic.id) + self.assertTrue(translation.get("summary"), topic.id) + self.assertTrue(translation.get("body"), topic.id) + if localizable_documentation_metadata_keys(topic): + self.assertEqual("1", topic.structured_translation_version, topic.id) + self.assertIn("de", topic.structured_translations, topic.id) + self.assertEqual((), documentation_structured_translation_issues(topic)) + + reference = next( + topic + for topic in topics + if topic.id == "dashboard.reference.layout-and-widgets" + ) + self.assertEqual("reference", reference.metadata["kind"]) + def test_webui_guards_layout_and_nested_widget_drafts(self) -> None: page = (REPO_ROOT / "webui/src/features/dashboard/DashboardPage.tsx").read_text( encoding="utf-8" diff --git a/webui/package.json b/webui/package.json index 1050890..4fd8d42 100644 --- a/webui/package.json +++ b/webui/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/dashboard-webui", - "version": "0.1.18", + "version": "0.1.19", "private": true, "type": "module", "main": "src/index.ts",