diff --git a/frontend/src/features/admin/api/admin.api.ts b/frontend/src/features/admin/api/admin.api.ts index 0dfd2e0..4fa90d5 100644 --- a/frontend/src/features/admin/api/admin.api.ts +++ b/frontend/src/features/admin/api/admin.api.ts @@ -408,13 +408,23 @@ export const adminApi = { return response.data; }, - // Execute restore + // Execute restore (longer timeout since this is a long-running operation) restore: async (id: string, options?: ExecuteRestoreRequest): Promise<{ message: string }> => { - const response = await apiClient.post<{ message: string }>( - `/admin/backups/${id}/restore`, - options - ); - return response.data; + try { + const response = await apiClient.post<{ message: string }>( + `/admin/backups/${id}/restore`, + options, + { timeout: 120000 } // 2 minute timeout for restore operations + ); + return response.data; + } catch (error: any) { + // If a restore is already in progress, treat it as success since it will complete + const errorMessage = error?.response?.data?.error || error?.message || ''; + if (errorMessage.includes('already in progress')) { + return { message: 'Restore is in progress and will complete shortly' }; + } + throw error; + } }, // Schedules diff --git a/frontend/src/features/admin/hooks/useBackups.ts b/frontend/src/features/admin/hooks/useBackups.ts index e326974..dae1e5a 100644 --- a/frontend/src/features/admin/hooks/useBackups.ts +++ b/frontend/src/features/admin/hooks/useBackups.ts @@ -147,6 +147,7 @@ export const useExecuteRestore = () => { return useMutation({ mutationFn: ({ id, options }: { id: string; options?: ExecuteRestoreRequest }) => adminApi.backups.restore(id, options), + retry: false, onSuccess: (data) => { queryClient.invalidateQueries({ queryKey: backupKeys.all }); toast.success(data.message || 'Restore completed successfully'); diff --git a/frontend/src/features/admin/mobile/AdminBackupMobileScreen.tsx b/frontend/src/features/admin/mobile/AdminBackupMobileScreen.tsx index 87221dd..3305a67 100644 --- a/frontend/src/features/admin/mobile/AdminBackupMobileScreen.tsx +++ b/frontend/src/features/admin/mobile/AdminBackupMobileScreen.tsx @@ -152,7 +152,7 @@ export const AdminBackupMobileScreen: React.FC = () => { ); const handleExecuteRestore = useCallback(() => { - if (!selectedBackup) return; + if (!selectedBackup || executeRestoreMutation.isPending) return; executeRestoreMutation.mutate( { id: selectedBackup.id, options: { createSafetyBackup } }, { diff --git a/frontend/src/pages/admin/AdminBackupPage.tsx b/frontend/src/pages/admin/AdminBackupPage.tsx index c82a4ff..314f9fc 100644 --- a/frontend/src/pages/admin/AdminBackupPage.tsx +++ b/frontend/src/pages/admin/AdminBackupPage.tsx @@ -210,7 +210,7 @@ export const AdminBackupPage: React.FC = () => { ); const handleExecuteRestore = useCallback(() => { - if (!selectedBackup) return; + if (!selectedBackup || executeRestoreMutation.isPending) return; executeRestoreMutation.mutate( { id: selectedBackup.id, options: { createSafetyBackup } }, {