import { useMutation, useQuery } from "@tanstack/react-query"; import { Archive, RefreshCw } from "lucide-react"; import { getRepositoryStatsOptions, refreshRepositoryStatsMutation, } from "~/client/api-client/@tanstack/react-query.gen"; import type { GetRepositoryStatsResponse } from "~/client/api-client/types.gen"; import { ByteSize } from "~/client/components/bytes-size"; import { useRootLoaderData } from "~/client/hooks/use-root-loader-data"; import { Button } from "~/client/components/ui/button"; import { Card, CardTitle } from "~/client/components/ui/card"; import { Separator } from "~/client/components/ui/separator"; import { parseError } from "~/client/lib/errors"; import { cn } from "~/client/lib/utils"; import { toast } from "sonner"; type Props = { repositoryShortId: string; initialStats?: GetRepositoryStatsResponse; }; const toSafeNumber = (value: number | undefined) => { if (typeof value !== "number" || !Number.isFinite(value)) { return 0; } return Math.max(0, value); }; export function CompressionStatsChart({ repositoryShortId, initialStats }: Props) { const { locale } = useRootLoaderData(); const refreshStats = useMutation({ ...refreshRepositoryStatsMutation(), onSuccess: () => { toast.success("Repository stats refreshed"); }, onError: (mutationError) => { toast.error("Failed to refresh repository stats", { description: parseError(mutationError)?.message, }); }, }); const { data: stats, isPending, error, } = useQuery({ ...getRepositoryStatsOptions({ path: { shortId: repositoryShortId } }), retry: false, initialData: initialStats, }); const storedSize = toSafeNumber(stats?.total_size); const uncompressedSize = toSafeNumber(stats?.total_uncompressed_size); const savedSize = uncompressedSize > storedSize ? uncompressedSize - storedSize : 0; const compressionRatio = toSafeNumber(stats?.compression_ratio); const rawCompressionProgress = toSafeNumber(stats?.compression_progress); const compressionProgressPercent = Math.min(100, Math.max(0, rawCompressionProgress)); const snapshotsCount = Math.round(toSafeNumber(stats?.snapshots_count)); const hasStats = !!stats && (storedSize > 0 || uncompressedSize > 0 || snapshotsCount > 0); const storedPercent = Math.min(100, Math.max(0, uncompressedSize > 0 ? (storedSize / uncompressedSize) * 100 : 0)); return (
Compression Statistics

Loading compression statistics...

Failed to load compression statistics

{error?.message}

Stats will be populated after your first backup. You can also refresh them manually.

of data across {snapshotsCount} snapshots
On disk
= 80 })}>Freed by compression
freed
Ratio {compressionRatio > 0 ? `${compressionRatio.toFixed(2)}x` : "-"}
Snapshots {snapshotsCount.toLocaleString(locale)}
Compressed {compressionProgressPercent.toFixed(0)}%
); }