import { useQuery, useMutation } from "@tanstack/react-query"; import { Database, X, RefreshCw } from "lucide-react"; import { useState } from "react"; import { listBackupSchedulesOptions, listSnapshotsOptions, refreshSnapshotsMutation, } from "~/client/api-client/@tanstack/react-query.gen"; import { SnapshotsTable } from "~/client/components/snapshots-table"; import { Button } from "~/client/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/client/components/ui/card"; import { Input } from "~/client/components/ui/input"; import { Table, TableBody, TableCell, TableRow } from "~/client/components/ui/table"; import type { BackupSchedule, Repository, Snapshot } from "~/client/lib/types"; import { toast } from "sonner"; type Props = { repository: Repository; initialSnapshots?: Snapshot[]; initialBackupSchedules?: BackupSchedule[]; }; export const RepositorySnapshotsTabContent = ({ repository, initialSnapshots, initialBackupSchedules }: Props) => { const [searchQuery, setSearchQuery] = useState(""); const { data, isPending, failureReason } = useQuery({ ...listSnapshotsOptions({ path: { shortId: repository.shortId } }), initialData: initialSnapshots, }); const schedules = useQuery({ ...listBackupSchedulesOptions(), initialData: initialBackupSchedules, }); const refreshMutation = useMutation({ ...refreshSnapshotsMutation(), onSuccess: (data) => { toast.success(`Snapshot cache refreshed. Found ${data.count} snapshots.`); }, onError: (error) => { toast.error(`Failed to refresh snapshots: ${error.message}`); }, }); const handleRefresh = () => { refreshMutation.mutate({ path: { shortId: repository.shortId } }); }; const snapshots = data ?? []; const filteredSnapshots = snapshots.filter((snapshot: Snapshot) => { if (!searchQuery) return true; const searchLower = searchQuery.toLowerCase(); const backup = schedules.data?.find((b) => snapshot.tags.includes(b.shortId)); return ( snapshot.short_id.toLowerCase().includes(searchLower) || snapshot.paths.some((path) => path.toLowerCase().includes(searchLower)) || backup?.name?.toLowerCase().includes(searchLower) || backup?.volume?.name?.toLowerCase().includes(searchLower) ); }); const hasNoFilteredSnapshots = !filteredSnapshots.length; if (repository.status === "error") { return (

Repository error

This repository is in an error state and cannot be accessed.

{repository.lastError && (

{repository.lastError}

)}
); } if (failureReason) { return (

Failed to Load Snapshots

{failureReason.message}

); } if (isPending) { return (

Loading snapshots

); } if (!snapshots.length) { return (

No snapshots yet

Snapshots are point-in-time backups of your data. Create your first backup to see it here.

); } return (
Snapshots Backup snapshots stored in this repository. Total: {snapshots.length}
setSearchQuery(e.target.value)} />
{hasNoFilteredSnapshots ? (

No snapshots match your search.

) : ( )}
{hasNoFilteredSnapshots ? "No snapshots match filters." : `Showing ${filteredSnapshots.length} of ${snapshots.length}`}
); };