Add CalDAV outbox recovery UI

This commit is contained in:
2026-08-02 15:57:01 +02:00
parent 4e05ab2c3e
commit 77a40ec2f9
14 changed files with 737 additions and 14 deletions
@@ -5,7 +5,7 @@ import {
type ChangeEvent,
type FormEvent,
} from "react";
import { RefreshCw, Trash2 } from "lucide-react";
import { ListChecks, RefreshCw, Trash2 } from "lucide-react";
import {
Button,
ColorPickerField,
@@ -101,6 +101,7 @@ export function CalendarCollectionDialog({
onSave,
onRequestDelete,
onSync,
onOpenOutbox,
onDiscover
@@ -116,7 +117,7 @@ export function CalendarCollectionDialog({
}: {state: CalendarCollectionDialogState;settings: ApiSettings;source: CalendarSyncSource | null;saving: boolean;syncingSourceId: string;canWrite: boolean;canDelete: boolean;canManageSources: boolean;canSyncSources: boolean;onCancel: () => void;onSave: (payload: CalendarCollectionFormPayload) => Promise<boolean>;onRequestDelete: (calendar: CalendarCollection, eventCount: number | null, loadingEventCount: boolean) => void;onSync: (source: CalendarSyncSource, payload?: {password?: string | null;bearer_token?: string | null;force_full?: boolean;}) => Promise<void>;onDiscover: (payload: CalendarCalDavDiscoveryPayload) => Promise<{calendars: CalendarCalDavDiscoveryCandidate[];}>;}) {
}: {state: CalendarCollectionDialogState;settings: ApiSettings;source: CalendarSyncSource | null;saving: boolean;syncingSourceId: string;canWrite: boolean;canDelete: boolean;canManageSources: boolean;canSyncSources: boolean;onCancel: () => void;onSave: (payload: CalendarCollectionFormPayload) => Promise<boolean>;onRequestDelete: (calendar: CalendarCollection, eventCount: number | null, loadingEventCount: boolean) => void;onSync: (source: CalendarSyncSource, payload?: {password?: string | null;bearer_token?: string | null;force_full?: boolean;}) => Promise<void>;onOpenOutbox: (source: CalendarSyncSource) => void;onDiscover: (payload: CalendarCalDavDiscoveryPayload) => Promise<{calendars: CalendarCalDavDiscoveryCandidate[];}>;}) {
const calendar = state.kind === "edit" ? state.calendar : null;
const isEdit = Boolean(calendar);
const [sourceMode, setSourceMode] = useState<CalendarSourceMode>(source ? calendarSourceModeForSource(source) : "local");
@@ -559,6 +560,11 @@ export function CalendarCollectionDialog({
<Button type="button" onClick={() => void onSync(source, { ...syncTransientPayload(effectiveAuthType, password, bearerToken), force_full: true })} disabled={saving || syncing || !canSyncSources}>
i18n:govoplan-calendar.full_sync.21b89c76
</Button>
{source.source_kind === "caldav" && canManageSources && (
<Button type="button" onClick={() => onOpenOutbox(source)} disabled={saving || syncing}>
<ListChecks size={16} /> i18n:govoplan-calendar.outbound_changes.7038a839
</Button>
)}
</div>
</div>
}