diff --git a/apps/client/app/api-client/@tanstack/react-query.gen.ts b/apps/client/app/api-client/@tanstack/react-query.gen.ts index d6611e1..7f47a15 100644 --- a/apps/client/app/api-client/@tanstack/react-query.gen.ts +++ b/apps/client/app/api-client/@tanstack/react-query.gen.ts @@ -36,6 +36,7 @@ import { updateBackupSchedule, getBackupScheduleForVolume, runBackupNow, + stopBackup, getSystemInfo, downloadResticPassword, } from "../sdk.gen"; @@ -94,9 +95,10 @@ import type { GetBackupScheduleForVolumeData, RunBackupNowData, RunBackupNowResponse, + StopBackupData, + StopBackupResponse, GetSystemInfoData, DownloadResticPasswordData, - DownloadResticPasswordError, DownloadResticPasswordResponse, } from "../types.gen"; import { client as _heyApiClient } from "../client.gen"; @@ -1108,6 +1110,45 @@ export const runBackupNowMutation = ( return mutationOptions; }; +export const stopBackupQueryKey = (options: Options) => createQueryKey("stopBackup", options); + +/** + * Stop a backup that is currently in progress + */ +export const stopBackupOptions = (options: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await stopBackup({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: stopBackupQueryKey(options), + }); +}; + +/** + * Stop a backup that is currently in progress + */ +export const stopBackupMutation = ( + options?: Partial>, +): UseMutationOptions> => { + const mutationOptions: UseMutationOptions> = { + mutationFn: async (localOptions) => { + const { data } = await stopBackup({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + export const getSystemInfoQueryKey = (options?: Options) => createQueryKey("getSystemInfo", options); /** @@ -1154,14 +1195,10 @@ export const downloadResticPasswordOptions = (options?: Options>, -): UseMutationOptions< - DownloadResticPasswordResponse, - DownloadResticPasswordError, - Options -> => { +): UseMutationOptions> => { const mutationOptions: UseMutationOptions< DownloadResticPasswordResponse, - DownloadResticPasswordError, + DefaultError, Options > = { mutationFn: async (localOptions) => { diff --git a/apps/client/app/api-client/sdk.gen.ts b/apps/client/app/api-client/sdk.gen.ts index 3222a98..f5d1dc2 100644 --- a/apps/client/app/api-client/sdk.gen.ts +++ b/apps/client/app/api-client/sdk.gen.ts @@ -74,11 +74,13 @@ import type { GetBackupScheduleForVolumeResponses, RunBackupNowData, RunBackupNowResponses, + StopBackupData, + StopBackupResponses, + StopBackupErrors, GetSystemInfoData, GetSystemInfoResponses, DownloadResticPasswordData, DownloadResticPasswordResponses, - DownloadResticPasswordErrors, } from "./types.gen"; import { client as _heyApiClient } from "./client.gen"; @@ -533,6 +535,16 @@ export const runBackupNow = ( }); }; +/** + * Stop a backup that is currently in progress + */ +export const stopBackup = (options: Options) => { + return (options.client ?? _heyApiClient).post({ + url: "/api/v1/backups/{scheduleId}/stop", + ...options, + }); +}; + /** * Get system information including available capabilities */ @@ -551,11 +563,7 @@ export const getSystemInfo = ( export const downloadResticPassword = ( options?: Options, ) => { - return (options?.client ?? _heyApiClient).post< - DownloadResticPasswordResponses, - DownloadResticPasswordErrors, - ThrowOnError - >({ + return (options?.client ?? _heyApiClient).post({ url: "/api/v1/system/restic-password", ...options, headers: { diff --git a/apps/client/app/api-client/types.gen.ts b/apps/client/app/api-client/types.gen.ts index 09b90cd..b1c526d 100644 --- a/apps/client/app/api-client/types.gen.ts +++ b/apps/client/app/api-client/types.gen.ts @@ -1480,6 +1480,33 @@ export type RunBackupNowResponses = { export type RunBackupNowResponse = RunBackupNowResponses[keyof RunBackupNowResponses]; +export type StopBackupData = { + body?: never; + path: { + scheduleId: string; + }; + query?: never; + url: "/api/v1/backups/{scheduleId}/stop"; +}; + +export type StopBackupErrors = { + /** + * No backup is currently running for this schedule + */ + 409: unknown; +}; + +export type StopBackupResponses = { + /** + * Backup stopped successfully + */ + 200: { + success: boolean; + }; +}; + +export type StopBackupResponse = StopBackupResponses[keyof StopBackupResponses]; + export type GetSystemInfoData = { body?: never; path?: never; @@ -1509,17 +1536,6 @@ export type DownloadResticPasswordData = { url: "/api/v1/system/restic-password"; }; -export type DownloadResticPasswordErrors = { - /** - * Authentication required or incorrect password - */ - 401: { - message?: string; - }; -}; - -export type DownloadResticPasswordError = DownloadResticPasswordErrors[keyof DownloadResticPasswordErrors]; - export type DownloadResticPasswordResponses = { /** * Restic password file content diff --git a/apps/client/app/modules/backups/components/schedule-summary.tsx b/apps/client/app/modules/backups/components/schedule-summary.tsx index f1496e8..edb8b2b 100644 --- a/apps/client/app/modules/backups/components/schedule-summary.tsx +++ b/apps/client/app/modules/backups/components/schedule-summary.tsx @@ -1,4 +1,4 @@ -import { Pencil, Play, Trash2 } from "lucide-react"; +import { Pencil, Play, Square, Trash2 } from "lucide-react"; import { useMemo, useState } from "react"; import { OnOff } from "~/components/onoff"; import { Button } from "~/components/ui/button"; @@ -18,12 +18,14 @@ type Props = { schedule: BackupSchedule; handleToggleEnabled: (enabled: boolean) => void; handleRunBackupNow: () => void; + handleStopBackup: () => void; handleDeleteSchedule: () => void; setIsEditMode: (isEdit: boolean) => void; }; export const ScheduleSummary = (props: Props) => { - const { schedule, handleToggleEnabled, handleRunBackupNow, handleDeleteSchedule, setIsEditMode } = props; + const { schedule, handleToggleEnabled, handleRunBackupNow, handleStopBackup, handleDeleteSchedule, setIsEditMode } = + props; const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const summary = useMemo(() => { @@ -75,16 +77,17 @@ export const ScheduleSummary = (props: Props) => {
- + {schedule.lastBackupStatus === "in_progress" ? ( + + ) : ( + + )}