From 195aea052ee4bba0c1dc3bc33af580f8a07e81a3 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Sat, 8 Nov 2025 09:24:30 +0100 Subject: [PATCH] refactor(backup-details): load snapshots after page load --- .../backups/components/snapshot-timeline.tsx | 26 ++++++++++-- .../modules/backups/routes/backup-details.tsx | 42 ++++++++----------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/apps/client/app/modules/backups/components/snapshot-timeline.tsx b/apps/client/app/modules/backups/components/snapshot-timeline.tsx index 2833f49..001cf06 100644 --- a/apps/client/app/modules/backups/components/snapshot-timeline.tsx +++ b/apps/client/app/modules/backups/components/snapshot-timeline.tsx @@ -2,23 +2,41 @@ import type { ListSnapshotsResponse } from "~/api-client/types.gen"; import { cn } from "~/lib/utils"; import { Card } from "~/components/ui/card"; import { ByteSize } from "~/components/bytes-size"; +import { useEffect } from "react"; interface Props { snapshots: ListSnapshotsResponse; - snapshotId: string; + snapshotId?: string; + loading?: boolean; onSnapshotSelect: (snapshotId: string) => void; } export const SnapshotTimeline = (props: Props) => { - const { snapshots, snapshotId, onSnapshotSelect } = props; + const { snapshots, snapshotId, loading, onSnapshotSelect } = props; + + useEffect(() => { + if (!snapshotId && snapshots.length > 0) { + onSnapshotSelect(snapshots[snapshots.length - 1].short_id); + } + }, [snapshotId, snapshots, onSnapshotSelect]); + + if (loading) { + return ( + +
+

Loading snapshots...

+
+
+ ); + } if (snapshots.length === 0) { return ( -
+

No snapshots available

-
+ ); } diff --git a/apps/client/app/modules/backups/routes/backup-details.tsx b/apps/client/app/modules/backups/routes/backup-details.tsx index 4207fe8..589852e 100644 --- a/apps/client/app/modules/backups/routes/backup-details.tsx +++ b/apps/client/app/modules/backups/routes/backup-details.tsx @@ -14,7 +14,7 @@ import { parseError } from "~/lib/errors"; import { getCronExpression } from "~/utils/utils"; import { CreateScheduleForm, type BackupScheduleFormValues } from "../components/create-schedule-form"; import { ScheduleSummary } from "../components/schedule-summary"; -import { getBackupSchedule, listSnapshots } from "~/api-client"; +import { getBackupSchedule } from "~/api-client"; import type { Route } from "./+types/backup-details"; import { SnapshotFileBrowser } from "../components/snapshot-file-browser"; import { SnapshotTimeline } from "../components/snapshot-timeline"; @@ -24,34 +24,27 @@ export const clientLoader = async ({ params }: Route.LoaderArgs) => { if (!data) return redirect("/backups"); - const snapshots = await listSnapshots({ - path: { name: data.repository.name }, - query: { backupId: params.id }, - }); - - if (snapshots.data) return { snapshots: snapshots.data, schedule: data }; - return { snapshots: [], schedule: data }; + return data; }; export default function ScheduleDetailsPage({ params, loaderData }: Route.ComponentProps) { const navigate = useNavigate(); const [isEditMode, setIsEditMode] = useState(false); const formId = useId(); - const [selectedSnapshotId, setSelectedSnapshotId] = useState(loaderData.snapshots.at(-1)?.short_id ?? ""); + const [selectedSnapshotId, setSelectedSnapshotId] = useState(); const { data: schedule } = useQuery({ ...getBackupScheduleOptions({ path: { scheduleId: params.id }, }), - initialData: loaderData.schedule, + initialData: loaderData, }); - const { data: snapshots } = useQuery({ + const { data: snapshots, isLoading } = useQuery({ ...listSnapshotsOptions({ path: { name: schedule.repository.name }, query: { backupId: schedule.id.toString() }, }), - initialData: loaderData.snapshots, }); const upsertSchedule = useMutation({ @@ -166,7 +159,7 @@ export default function ScheduleDetailsPage({ params, loaderData }: Route.Compon ); } - const selectedSnapshot = snapshots.find((s) => s.short_id === selectedSnapshotId); + const selectedSnapshot = snapshots?.find((s) => s.short_id === selectedSnapshotId); return (
@@ -177,19 +170,18 @@ export default function ScheduleDetailsPage({ params, loaderData }: Route.Compon setIsEditMode={setIsEditMode} schedule={schedule} /> + {selectedSnapshot && ( - <> - - - + )}
);