feat: enhance backups page with live data loading and backup job management

Implemented live data fetching for servers and backups on the backups page, replacing static initial data. Added functionality for manual backup creation and job status tracking, including error handling and UI updates. Updated the network map layout to improve node prioritization and visual representation of server roles.

Also, registered new backups API routes in the backend for improved data handling.
This commit is contained in:
Denozordec
2026-05-07 14:24:58 +07:00
parent 6d8379501c
commit 84ecd4f061
24 changed files with 146391 additions and 54 deletions
+68
View File
@@ -0,0 +1,68 @@
import { requestJson } from "@/shared/api/http-client"
export type BackupItem = {
id: string
serverId: string
serverName: string
filename: string
sizeBytes: number
createdAt: string
kind: "manual"
notes?: string
}
type CreateBackupResponse = {
created: BackupItem[]
failures: Array<{ serverId: string; error: string }>
}
export type CreateBackupJobResponse = {
jobId: string
status: "queued" | "running" | "done" | "failed"
total: number
completed: number
}
export type BackupJobStatusResponse = {
id: string
status: "queued" | "running" | "done" | "failed"
requestedAt: string
startedAt?: string
finishedAt?: string
total: number
completed: number
created: BackupItem[]
failures: Array<{ serverId: string; error: string }>
}
export async function listBackups(baseUrl: string): Promise<BackupItem[]> {
return requestJson<BackupItem[]>(baseUrl, "/api/backups")
}
export async function createBackups(
baseUrl: string,
payload: { serverIds: string[]; notes?: string },
): Promise<CreateBackupResponse> {
return requestJson<CreateBackupResponse>(baseUrl, "/api/backups/create", {
method: "POST",
body: JSON.stringify(payload),
})
}
export async function createBackupsAsync(
baseUrl: string,
payload: { serverIds: string[]; notes?: string },
): Promise<CreateBackupJobResponse> {
return requestJson<CreateBackupJobResponse>(baseUrl, "/api/backups/create", {
method: "POST",
body: JSON.stringify(payload),
})
}
export async function getBackupJob(baseUrl: string, jobId: string): Promise<BackupJobStatusResponse> {
return requestJson<BackupJobStatusResponse>(baseUrl, `/api/backups/jobs/${jobId}`)
}
export async function deleteBackup(baseUrl: string, id: string): Promise<void> {
await requestJson<void>(baseUrl, `/api/backups/${id}`, { method: "DELETE" })
}