import { useQuery } from "@tanstack/react-query"; import { Database, Pencil, Play, Trash2 } from "lucide-react"; import { useMemo, useState } from "react"; import { listSnapshotsOptions } from "~/api-client/@tanstack/react-query.gen"; import { ByteSize } from "~/components/bytes-size"; import { OnOff } from "~/components/onoff"; import { SnapshotsTable } from "~/components/snapshots-table"; import { Button } from "~/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/components/ui/card"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, } from "~/components/ui/alert-dialog"; import type { BackupSchedule, Repository, Volume } from "~/lib/types"; type Props = { volume: Volume; schedule: BackupSchedule; repository: Repository; handleToggleEnabled: (enabled: boolean) => void; handleRunBackupNow: () => void; handleDeleteSchedule: () => void; setIsEditMode: (isEdit: boolean) => void; isDeleting?: boolean; }; export const ScheduleSummary = (props: Props) => { const { volume, schedule, repository, handleToggleEnabled, handleRunBackupNow, handleDeleteSchedule, setIsEditMode, isDeleting, } = props; const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const { data: snapshots, isLoading: loadingSnapshots } = useQuery({ ...listSnapshotsOptions({ path: { name: repository.name }, query: { volumeId: volume.id.toString() }, }), refetchInterval: 10000, refetchOnWindowFocus: true, }); const summary = useMemo(() => { const scheduleLabel = schedule ? schedule.cronExpression : "-"; const retentionParts: string[] = []; if (schedule?.retentionPolicy) { const rp = schedule.retentionPolicy; if (rp.keepLast) retentionParts.push(`${rp.keepLast} last`); if (rp.keepHourly) retentionParts.push(`${rp.keepHourly} hourly`); if (rp.keepDaily) retentionParts.push(`${rp.keepDaily} daily`); if (rp.keepWeekly) retentionParts.push(`${rp.keepWeekly} weekly`); if (rp.keepMonthly) retentionParts.push(`${rp.keepMonthly} monthly`); if (rp.keepYearly) retentionParts.push(`${rp.keepYearly} yearly`); } return { vol: volume.name, scheduleLabel, repositoryLabel: schedule.repositoryId || "No repository selected", retentionLabel: retentionParts.length > 0 ? retentionParts.join(" • ") : "No retention policy", }; }, [schedule, volume.name]); const handleConfirmDelete = () => { setShowDeleteConfirm(false); handleDeleteSchedule(); }; return (
Backup schedule Automated backup configuration for volume {volume.name}

Schedule

{summary.scheduleLabel}

Repository

{repository.name}

Last backup

{schedule.lastBackupAt ? new Date(schedule.lastBackupAt).toLocaleString() : "Never"}

Next backup

{schedule.nextBackupAt ? new Date(schedule.nextBackupAt).toLocaleString() : "Never"}

Status

{schedule.lastBackupStatus === "success" && "✓ Success"} {schedule.lastBackupStatus === "error" && "✗ Error"} {!schedule.lastBackupStatus && "—"}

Delete backup schedule? Are you sure you want to delete this backup schedule for {volume.name}? This action cannot be undone. Existing snapshots will not be deleted.
Cancel Delete schedule
Snapshots Backup snapshots for this volume. Total: {snapshots?.snapshots.length}
{loadingSnapshots && !snapshots ? (

Loading snapshots...

) : !snapshots ? (

No snapshots yet

Snapshots are point-in-time backups of your data. The next scheduled backup will create the first snapshot.

) : ( <>
{`Showing ${snapshots.snapshots.length} of ${snapshots.snapshots.length}`} Total size:  sum + s.size, 0)} base={1024} maximumFractionDigits={1} />
)}
); };