import { useCallback } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { FileIcon, RotateCcw, Trash2 } from "lucide-react"; import { Link } from "react-router"; import { FileTree } from "~/client/components/file-tree"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/client/components/ui/card"; import { Button, buttonVariants } from "~/client/components/ui/button"; import type { Snapshot } from "~/client/lib/types"; import { listSnapshotFilesOptions } from "~/client/api-client/@tanstack/react-query.gen"; import { useFileBrowser } from "~/client/hooks/use-file-browser"; interface Props { snapshot: Snapshot; repositoryName: string; backupId?: string; onDeleteSnapshot?: (snapshotId: string) => void; isDeletingSnapshot?: boolean; } export const SnapshotFileBrowser = (props: Props) => { const { snapshot, repositoryName, backupId, onDeleteSnapshot, isDeletingSnapshot } = props; const queryClient = useQueryClient(); const volumeBasePath = snapshot.paths[0]?.match(/^(.*?_data)(\/|$)/)?.[1] || "/"; const { data: filesData, isLoading: filesLoading } = useQuery({ ...listSnapshotFilesOptions({ path: { name: repositoryName, snapshotId: snapshot.short_id }, query: { path: volumeBasePath }, }), }); const stripBasePath = useCallback( (path: string): string => { if (!volumeBasePath) return path; if (path === volumeBasePath) return "/"; if (path.startsWith(`${volumeBasePath}/`)) { const stripped = path.slice(volumeBasePath.length); return stripped; } return path; }, [volumeBasePath], ); const addBasePath = useCallback( (displayPath: string): string => { const vbp = volumeBasePath === "/" ? "" : volumeBasePath; if (!vbp) return displayPath; if (displayPath === "/") return vbp; return `${vbp}${displayPath}`; }, [volumeBasePath], ); const fileBrowser = useFileBrowser({ initialData: filesData, isLoading: filesLoading, fetchFolder: async (path) => { return await queryClient.ensureQueryData( listSnapshotFilesOptions({ path: { name: repositoryName, snapshotId: snapshot.short_id }, query: { path }, }), ); }, prefetchFolder: (path) => { queryClient.prefetchQuery( listSnapshotFilesOptions({ path: { name: repositoryName, snapshotId: snapshot.short_id }, query: { path }, }), ); }, pathTransform: { strip: stripBasePath, add: addBasePath, }, }); return (
File Browser {`Viewing snapshot from ${new Date(snapshot?.time ?? 0).toLocaleString()}`}
Restore {onDeleteSnapshot && ( )}
{fileBrowser.isLoading && (

Loading files...

)} {fileBrowser.isEmpty && (

No files in this snapshot

)} {!fileBrowser.isLoading && !fileBrowser.isEmpty && (
)}
); };