diff --git a/src/govoplan_calendar/backend/manifest.py b/src/govoplan_calendar/backend/manifest.py
index 3a3c103..c5ee5b9 100644
--- a/src/govoplan_calendar/backend/manifest.py
+++ b/src/govoplan_calendar/backend/manifest.py
@@ -895,7 +895,9 @@ manifest = ModuleManifest(
id="calendar.manage-calendars-and-events",
title="Use calendars and events",
summary="Create calendar collections and work with all-day or timed events in continuous, month, week, workweek, and day views.",
- body="Calendar remembers the selected view and preferences. Events can be created, edited, moved, resized, repeated, imported, exported, or deleted when the current account has the corresponding permission. All-day events use dates rather than local clock times; timed events retain their timezone-aware start and end values. Scheduling may promote a selected tentative hold in place and submit unused holds for idempotent release through the neutral Calendar capability. Calendar owns the resulting local tombstone, synchronized outbox operation, retry and reconciliation evidence; an already released or absent event is an accepted replay rather than a duplicate failure.",
+ body="Documentation books sit beside Calendars, Calendar display, and the relevant event, source, "
+ "move, or recovery dialog title. Field help remains beside its label. "
+ "Calendar remembers the selected view and preferences. Events can be created, edited, moved, resized, repeated, imported, exported, or deleted when the current account has the corresponding permission. All-day events use dates rather than local clock times; timed events retain their timezone-aware start and end values. Scheduling may promote a selected tentative hold in place and submit unused holds for idempotent release through the neutral Calendar capability. Calendar owns the resulting local tombstone, synchronized outbox operation, retry and reconciliation evidence; an already released or absent event is an accepted replay rather than a duplicate failure.",
documentation_types=("user",),
audience=("user", "calendar_manager"),
related_modules=("scheduling", "notifications"),
@@ -907,6 +909,9 @@ manifest = ModuleManifest(
"Arbeitswochen- und Tagesansicht bearbeiten."
),
"body": (
+ "Dokumentationsbücher stehen neben Kalender, Kalenderanzeige und dem jeweiligen Dialogtitel "
+ "für Ereignisse, Quellen, Verschiebungen oder Wiederherstellung. Feldhilfe bleibt neben der "
+ "Feldbezeichnung. "
"Calendar merkt sich gewählte Ansicht und Präferenzen. Ereignisse können mit der entsprechenden Berechtigung angelegt, "
"bearbeitet, verschoben, in ihrer Dauer geändert, wiederholt, importiert, exportiert oder gelöscht werden. Ganztägige "
"Ereignisse verwenden Datumswerte statt lokaler Uhrzeiten; zeitgebundene Ereignisse bewahren zeitzonenbezogene Start- und "
@@ -939,7 +944,9 @@ manifest = ModuleManifest(
id="calendar.external-sources-and-sync",
title="Connect and synchronize external calendars",
summary="Calendar supports local collections, two-way CalDAV and Open-Xchange profiles, and read-only ICS/webcal, Microsoft Graph, and Exchange Web Services sources.",
- body="Each external source keeps its URL, synchronization direction, status, and credential reference with the Calendar collection. Open-Xchange uses the proven CalDAV transport while retaining connector-profile, identity/group-mapping, and resource-calendar references. Manual or scheduled synchronization records bounded outcomes. Scheduled source and outbox workers partition work by tenant entitlement; disabling Calendar preserves accepted operations and reports operator action instead of contacting a remote provider. CalDAV writes use conditional requests and durable outbox state; conflicts and unknown outcomes require synchronization or explicit reconciliation instead of blind repetition. Moving between two-way CalDAV calendars is an administrator-authorized migration batch: all destination resources must be copied before any source resource is conditionally deleted with its recorded ETag. Calendar and event changes remain locked while progress, conflicts, cancellation eligibility, and evidence are visible. Removing an external source removes the connection, while deleting a local calendar deletes its owned events after confirmation or transfer.",
+ body="Documentation books sit beside Calendars, Calendar display, and the relevant event, source, "
+ "move, or recovery dialog title. Field help remains beside its label. "
+ "Each external source keeps its URL, synchronization direction, status, and credential reference with the Calendar collection. Open-Xchange uses the proven CalDAV transport while retaining connector-profile, identity/group-mapping, and resource-calendar references. Manual or scheduled synchronization records bounded outcomes. Scheduled source and outbox workers partition work by tenant entitlement; disabling Calendar preserves accepted operations and reports operator action instead of contacting a remote provider. CalDAV writes use conditional requests and durable outbox state; conflicts and unknown outcomes require synchronization or explicit reconciliation instead of blind repetition. Moving between two-way CalDAV calendars is an administrator-authorized migration batch: all destination resources must be copied before any source resource is conditionally deleted with its recorded ETag. Calendar and event changes remain locked while progress, conflicts, cancellation eligibility, and evidence are visible. Removing an external source removes the connection, while deleting a local calendar deletes its owned events after confirmation or transfer.",
documentation_types=("admin", "user"),
audience=("user", "calendar_manager", "operator"),
related_modules=("connectors", "audit", "ops"),
@@ -951,6 +958,9 @@ manifest = ModuleManifest(
"ICS-/webcal-, Microsoft-Graph- und Exchange-Web-Services-Quellen."
),
"body": (
+ "Dokumentationsbücher stehen neben Kalender, Kalenderanzeige und dem jeweiligen Dialogtitel "
+ "für Ereignisse, Quellen, Verschiebungen oder Wiederherstellung. Feldhilfe bleibt neben der "
+ "Feldbezeichnung. "
"Jede externe Quelle hält URL, Synchronisationsrichtung, Status und Zugangsdatenverweis gemeinsam mit der "
"Calendar-Sammlung. Open-Xchange verwendet den bewährten CalDAV-Transport und bewahrt dabei Connector-Profil-, "
"Identitäts-/Gruppenzuordnungs- und Ressourcenkalenderverweise. Manuelle und geplante Synchronisation zeichnet begrenzte "
diff --git a/tests/test_interface_documentation_contract.py b/tests/test_interface_documentation_contract.py
index e6796b1..9dc815e 100644
--- a/tests/test_interface_documentation_contract.py
+++ b/tests/test_interface_documentation_contract.py
@@ -104,17 +104,20 @@ class CalendarInterfaceDocumentationContractTests(unittest.TestCase):
for component in (
"ActionBlockerHint",
"ConfirmDialog",
- "DocumentationHelpLink",
+ "titleHelp={}",
"useUnsavedDraftGuard",
):
self.assertIn(component, event_dialog)
for component in (
"ActionBlockerHint",
- "DocumentationHelpLink",
+ "titleHelp={}",
"useUnsavedDraftGuard",
):
self.assertIn(component, collection_dialog)
- for component in ("DocumentationHelpLink", "useUnsavedDraftGuard"):
+ for component in (
+ "titleHelp={}",
+ "useUnsavedDraftGuard",
+ ):
self.assertIn(component, settings_panel)
diff --git a/webui/src/features/calendar/CalendarCollectionDialogs.tsx b/webui/src/features/calendar/CalendarCollectionDialogs.tsx
index 4cf7e6d..fe6e28f 100644
--- a/webui/src/features/calendar/CalendarCollectionDialogs.tsx
+++ b/webui/src/features/calendar/CalendarCollectionDialogs.tsx
@@ -352,6 +352,7 @@ export function CalendarCollectionDialog({
}
size="large"
footerClassName="calendar-event-dialog-footer"
closeDisabled={saving}
@@ -373,9 +374,6 @@ export function CalendarCollectionDialog({
}>
-