diff --git a/apps/client/app/api-client/types.gen.ts b/apps/client/app/api-client/types.gen.ts index 6e61297..bd472e7 100644 --- a/apps/client/app/api-client/types.gen.ts +++ b/apps/client/app/api-client/types.gen.ts @@ -965,7 +965,7 @@ export type ListBackupSchedulesResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: "error" | "success" | null; + lastBackupStatus: "error" | "in_progress" | "success" | null; nextBackupAt: number | null; repository: { compressionMode: "auto" | "better" | "fastest" | "max" | "off" | null; @@ -1087,7 +1087,7 @@ export type CreateBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: "error" | "success" | null; + lastBackupStatus: "error" | "in_progress" | "success" | null; nextBackupAt: number | null; repositoryId: string; retentionPolicy: { @@ -1148,7 +1148,7 @@ export type GetBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: "error" | "success" | null; + lastBackupStatus: "error" | "in_progress" | "success" | null; nextBackupAt: number | null; repository: { compressionMode: "auto" | "better" | "fastest" | "max" | "off" | null; @@ -1271,7 +1271,7 @@ export type UpdateBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: "error" | "success" | null; + lastBackupStatus: "error" | "in_progress" | "success" | null; nextBackupAt: number | null; repositoryId: string; retentionPolicy: { @@ -1312,7 +1312,7 @@ export type GetBackupScheduleForVolumeResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: "error" | "success" | null; + lastBackupStatus: "error" | "in_progress" | "success" | null; nextBackupAt: number | null; repository: { compressionMode: "auto" | "better" | "fastest" | "max" | "off" | null; diff --git a/apps/client/app/modules/backups/components/backup-status-dot.tsx b/apps/client/app/modules/backups/components/backup-status-dot.tsx index dd497eb..db3c42b 100644 --- a/apps/client/app/modules/backups/components/backup-status-dot.tsx +++ b/apps/client/app/modules/backups/components/backup-status-dot.tsx @@ -1,11 +1,17 @@ import { cn } from "~/lib/utils"; import { Tooltip, TooltipContent, TooltipTrigger } from "~/components/ui/tooltip"; -type BackupStatus = "active" | "paused" | "error"; +type BackupStatus = "active" | "paused" | "error" | "in_progress"; -export const BackupStatusDot = ({ enabled, hasError }: { enabled: boolean; hasError?: boolean }) => { +export const BackupStatusDot = ({ + enabled, + hasError, + isInProgress, +}: { enabled: boolean; hasError?: boolean; isInProgress?: boolean }) => { let status: BackupStatus = "paused"; - if (hasError) { + if (isInProgress) { + status = "in_progress"; + } else if (hasError) { status = "error"; } else if (enabled) { status = "active"; @@ -30,6 +36,12 @@ export const BackupStatusDot = ({ enabled, hasError }: { enabled: boolean; hasEr animated: true, label: "Error", }, + in_progress: { + color: "bg-blue-500", + colorLight: "bg-blue-400", + animated: true, + label: "Backup in progress", + }, }[status]; return ( diff --git a/apps/client/app/modules/backups/components/schedule-summary.tsx b/apps/client/app/modules/backups/components/schedule-summary.tsx index 8b28d32..f1496e8 100644 --- a/apps/client/app/modules/backups/components/schedule-summary.tsx +++ b/apps/client/app/modules/backups/components/schedule-summary.tsx @@ -75,9 +75,15 @@ export const ScheduleSummary = (props: Props) => {
-
diff --git a/apps/client/app/modules/backups/routes/backup-details.tsx b/apps/client/app/modules/backups/routes/backup-details.tsx index d0f792a..2bad503 100644 --- a/apps/client/app/modules/backups/routes/backup-details.tsx +++ b/apps/client/app/modules/backups/routes/backup-details.tsx @@ -38,6 +38,8 @@ export default function ScheduleDetailsPage({ params, loaderData }: Route.Compon path: { scheduleId: params.id }, }), initialData: loaderData, + refetchInterval: 10000, + refetchOnWindowFocus: true, }); const { diff --git a/apps/client/app/modules/backups/routes/backups.tsx b/apps/client/app/modules/backups/routes/backups.tsx index 748de02..1bcaf55 100644 --- a/apps/client/app/modules/backups/routes/backups.tsx +++ b/apps/client/app/modules/backups/routes/backups.tsx @@ -73,7 +73,11 @@ export default function Backups({ loaderData }: Route.ComponentProps) { Volume {schedule.volume.name} - + diff --git a/apps/server/src/db/schema.ts b/apps/server/src/db/schema.ts index 5829055..018e880 100644 --- a/apps/server/src/db/schema.ts +++ b/apps/server/src/db/schema.ts @@ -88,7 +88,7 @@ export const backupSchedulesTable = sqliteTable("backup_schedules_table", { excludePatterns: text("exclude_patterns", { mode: "json" }).$type().default([]), includePatterns: text("include_patterns", { mode: "json" }).$type().default([]), lastBackupAt: int("last_backup_at", { mode: "number" }), - lastBackupStatus: text("last_backup_status").$type<"success" | "error">(), + lastBackupStatus: text("last_backup_status").$type<"success" | "error" | "in_progress">(), lastBackupError: text("last_backup_error"), nextBackupAt: int("next_backup_at", { mode: "number" }), createdAt: int("created_at", { mode: "number" }).notNull().default(sql`(unixepoch())`), diff --git a/apps/server/src/modules/backups/backups.dto.ts b/apps/server/src/modules/backups/backups.dto.ts index 9ec4677..ce0b43c 100644 --- a/apps/server/src/modules/backups/backups.dto.ts +++ b/apps/server/src/modules/backups/backups.dto.ts @@ -25,7 +25,7 @@ const backupScheduleSchema = type({ excludePatterns: "string[] | null", includePatterns: "string[] | null", lastBackupAt: "number | null", - lastBackupStatus: "'success' | 'error' | null", + lastBackupStatus: "'success' | 'error' | 'in_progress' | null", lastBackupError: "string | null", nextBackupAt: "number | null", createdAt: "number", diff --git a/apps/server/src/modules/backups/backups.service.ts b/apps/server/src/modules/backups/backups.service.ts index 89f6d91..cb62035 100644 --- a/apps/server/src/modules/backups/backups.service.ts +++ b/apps/server/src/modules/backups/backups.service.ts @@ -181,6 +181,11 @@ const executeBackup = async (scheduleId: number, manual = false) => { logger.info(`Starting backup for volume ${volume.name} to repository ${repository.name}`); + await db + .update(backupSchedulesTable) + .set({ lastBackupStatus: "in_progress", updatedAt: Date.now() }) + .where(eq(backupSchedulesTable.id, scheduleId)); + try { const volumePath = getVolumePath(volume.name);