import { useMutation } from "@tanstack/react-query"; import { useState } from "react"; import { toast } from "sonner"; import { Pencil, Square, Stethoscope, Trash2, Unlock } from "lucide-react"; import { Card } from "~/client/components/ui/card"; import { Button } from "~/client/components/ui/button"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, } from "~/client/components/ui/alert-dialog"; import type { Repository } from "~/client/lib/types"; import { formatDateTime, formatTimeAgo } from "~/client/lib/datetime"; import { cancelDoctorMutation, deleteRepositoryMutation, startDoctorMutation, unlockRepositoryMutation, } from "~/client/api-client/@tanstack/react-query.gen"; import type { RepositoryConfig } from "~/schemas/restic"; import { DoctorReport } from "../components/doctor-report"; import { parseError } from "~/client/lib/errors"; import { useNavigate } from "@tanstack/react-router"; import { CompressionStatsChart } from "../components/compression-stats-chart"; type Props = { repository: Repository; }; const getEffectiveLocalPath = (repository: Repository): string | null => { if (repository.config.backend !== "local") return null; return repository.config.path; }; export const RepositoryInfoTabContent = ({ repository }: Props) => { const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const navigate = useNavigate(); const effectiveLocalPath = getEffectiveLocalPath(repository); const deleteRepo = useMutation({ ...deleteRepositoryMutation(), onSuccess: () => { toast.success("Repository deleted successfully"); void navigate({ to: "/repositories" }); }, onError: (error) => { toast.error("Failed to delete repository", { description: parseError(error)?.message, }); }, }); const startDoctor = useMutation({ ...startDoctorMutation(), onError: (error) => { toast.error("Failed to start doctor", { description: parseError(error)?.message, }); }, }); const cancelDoctor = useMutation({ ...cancelDoctorMutation(), onSuccess: () => { toast.info("Doctor operation cancelled"); }, onError: (error) => { toast.error("Failed to cancel doctor", { description: parseError(error)?.message, }); }, }); const unlockRepo = useMutation({ ...unlockRepositoryMutation(), onSuccess: () => { toast.success("Repository unlocked successfully"); }, onError: (error) => { toast.error("Failed to unlock repository", { description: parseError(error)?.message, }); }, }); const handleConfirmDelete = () => { setShowDeleteConfirm(false); deleteRepo.mutate({ path: { shortId: repository.shortId } }); }; const config = repository.config as RepositoryConfig; return ( <>
Repository Settings
{repository.status === "doctor" ? ( ) : ( )}

Current Configuration

Name

{repository.name}

Compression mode

{repository.compressionMode || "off"}

Repository Information

Backend

{repository.type}

Status

{repository.status || "unknown"}

{effectiveLocalPath && (
Local path

{effectiveLocalPath}

)}
Created at

{formatDateTime(repository.createdAt)}

Last checked

{formatTimeAgo(repository.lastChecked)}

{config.cacert && (
CA Certificate

configured

)} {"insecureTls" in config && (
TLS Certificate Validation

{config.insecureTls ? ( disabled ) : ( enabled )}

)}
{repository.lastError && (

Last Error

{repository.lastError}

)}

Configuration

{JSON.stringify(repository.config, null, 2)}
Delete repository? Are you sure you want to delete the repository {repository.name}? This will not remove the actual data from the backend storage, only the repository configuration will be deleted.

All backup schedules associated with this repository will also be removed.
Cancel Delete repository
); };