diff --git a/.gitignore b/.gitignore index 8122a126..644f0800 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ openapi-ts-error-*.log tmp/ qa-output +.worktrees/ diff --git a/app/client/api-client/types.gen.ts b/app/client/api-client/types.gen.ts index 1198641c..58102104 100644 --- a/app/client/api-client/types.gen.ts +++ b/app/client/api-client/types.gen.ts @@ -204,8 +204,8 @@ export type GetPublicSsoProvidersResponses = { */ 200: { providers: Array<{ - organizationSlug: string; providerId: string; + organizationSlug: string; }>; }; }; @@ -224,20 +224,20 @@ export type GetSsoSettingsResponses = { * SSO settings for the active organization */ 200: { - invitations: Array<{ - email: string; - expiresAt: string; - id: string; - role: string; - status: string; - }>; providers: Array<{ - autoLinkMatchingEmails: boolean; - domain: string; - issuer: string; - organizationId: string | null; providerId: string; type: string; + issuer: string; + domain: string; + autoLinkMatchingEmails: boolean; + organizationId: string | null; + }>; + invitations: Array<{ + id: string; + email: string; + role: string; + status: string; + expiresAt: string; }>; }; }; diff --git a/app/client/modules/backups/components/backup-progress-card.tsx b/app/client/modules/backups/components/backup-progress-card.tsx index 053ac28d..8381d26c 100644 --- a/app/client/modules/backups/components/backup-progress-card.tsx +++ b/app/client/modules/backups/components/backup-progress-card.tsx @@ -46,6 +46,7 @@ export const BackupProgressCard = ({ scheduleShortId, initialProgress }: Props) const currentFile = progress?.current_files?.[0] || ""; const fileName = currentFile.split("/").pop() || currentFile; const speed = progress ? formatBytes(progress.bytes_done / progress.seconds_elapsed) : null; + const eta = progress?.seconds_remaining ? formatDuration(progress.seconds_remaining) : null; return ( @@ -96,6 +97,10 @@ export const BackupProgressCard = ({ scheduleShortId, initialProgress }: Props) {progress ? (progress.seconds_elapsed > 0 ? `${speed?.text} ${speed?.unit}/s` : "Calculating...") : "—"}

+
+

ETA

+

{progress ? (eta ?? "Calculating...") : "—"}

+
diff --git a/app/schemas/restic-dto.ts b/app/schemas/restic-dto.ts index e7185c7b..a5043966 100644 --- a/app/schemas/restic-dto.ts +++ b/app/schemas/restic-dto.ts @@ -31,6 +31,7 @@ export const resticBackupOutputSchema = resticBackupRunSummarySchema.extend({ export const resticBackupProgressMetricsSchema = z.object({ seconds_elapsed: z.number(), + seconds_remaining: z.number().default(0), percent_done: z.number(), total_files: z.number(), files_done: z.number(), diff --git a/app/server/utils/restic/commands/backup.ts b/app/server/utils/restic/commands/backup.ts index 56094bde..89d92405 100644 --- a/app/server/utils/restic/commands/backup.ts +++ b/app/server/utils/restic/commands/backup.ts @@ -107,6 +107,10 @@ export const backup = async ( if (options.onProgress) { try { const jsonData = JSON.parse(data); + if (jsonData.message_type !== "status") { + return; + } + const progressResult = resticBackupProgressSchema.safeParse(jsonData); if (progressResult.success) { options.onProgress(progressResult.data); diff --git a/app/server/utils/restic/commands/restore.ts b/app/server/utils/restic/commands/restore.ts index da7ff169..16d5d16c 100644 --- a/app/server/utils/restic/commands/restore.ts +++ b/app/server/utils/restic/commands/restore.ts @@ -100,6 +100,10 @@ export const restore = async ( if (options.onProgress) { try { const jsonData = JSON.parse(data); + if (jsonData.message_type !== "status") { + return; + } + const progress = restoreProgressSchema.safeParse(jsonData); if (progress.success) { options.onProgress(progress.data);