From dde8c50e55954d9eabfe13f752dd2d4b7e17426b Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Wed, 9 Sep 2026 02:03:12 +0200 Subject: [PATCH] fix(ui): align contextual documentation with headings Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete. --- src/govoplan_calendar/backend/manifest.py | 14 ++++++++++++-- tests/test_interface_documentation_contract.py | 9 ++++++--- .../calendar/CalendarCollectionDialogs.tsx | 8 ++------ .../src/features/calendar/CalendarEventDialog.tsx | 4 +--- .../features/calendar/CalendarMigrationDialog.tsx | 2 +- .../src/features/calendar/CalendarOutboxDialog.tsx | 2 +- webui/src/features/calendar/CalendarPage.tsx | 4 ++-- .../features/calendar/CalendarSettingsPanel.tsx | 5 +---- 8 files changed, 26 insertions(+), 22 deletions(-) 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({ }> -
- -
{migrationLocked && ( } className="calendar-delete-dialog" footerClassName="calendar-event-dialog-footer" closeDisabled={saving} @@ -689,9 +688,6 @@ export function CalendarCollectionDeleteDialog({ }>
-
- -

{loadingEventCount ? "i18n:govoplan-calendar.loading_event_count.716ad3c2" : diff --git a/webui/src/features/calendar/CalendarEventDialog.tsx b/webui/src/features/calendar/CalendarEventDialog.tsx index 8e6723c..9457d75 100644 --- a/webui/src/features/calendar/CalendarEventDialog.tsx +++ b/webui/src/features/calendar/CalendarEventDialog.tsx @@ -281,6 +281,7 @@ export function CalendarEventDialog({

} className="calendar-vevent-dialog" footerClassName="calendar-event-dialog-footer" closeDisabled={saving} @@ -302,9 +303,6 @@ export function CalendarEventDialog({ }> -
- -
{!canWrite && ( } className="calendar-migration-dialog" closeDisabled={working} onClose={onClose} @@ -113,7 +114,6 @@ export function CalendarMigrationDialog({
) : (
- {error && ( {error} diff --git a/webui/src/features/calendar/CalendarOutboxDialog.tsx b/webui/src/features/calendar/CalendarOutboxDialog.tsx index f7c6032..3e5b56d 100644 --- a/webui/src/features/calendar/CalendarOutboxDialog.tsx +++ b/webui/src/features/calendar/CalendarOutboxDialog.tsx @@ -95,6 +95,7 @@ export function CalendarOutboxDialog({ } className="calendar-outbox-dialog" closeDisabled={Boolean(busyOperationId)} onClose={onClose} @@ -111,7 +112,6 @@ export function CalendarOutboxDialog({ >

{calendar.name}

- {error && {error}} diff --git a/webui/src/features/calendar/CalendarPage.tsx b/webui/src/features/calendar/CalendarPage.tsx index 3fc32bb..cd4a659 100644 --- a/webui/src/features/calendar/CalendarPage.tsx +++ b/webui/src/features/calendar/CalendarPage.tsx @@ -13,6 +13,7 @@ import { ToolbarGroup, ActionToolbar, Button, DismissibleAlert, DocumentationHelpLink, + TextWithHelp, LoadingFrame, SegmentedControl, TableActionGroup, @@ -799,7 +800,7 @@ export default function CalendarPage({ settings, auth }: {settings: ApiSettings;