import { forwardRef, useImperativeHandle, useState, useCallback, useEffect, } from "react"; import { useTranslation } from "react-i18next"; import { BaseDialog, DialogRef } from "@/components/base"; import getSystem from "@/utils/get-system"; import { BaseLoadingOverlay } from "@/components/base"; import dayjs from "dayjs"; import customParseFormat from "dayjs/plugin/customParseFormat"; import { BackupTableViewer, BackupFile, DEFAULT_ROWS_PER_PAGE, } from "./backup-table-viewer"; import { BackupConfigViewer } from "./backup-config-viewer"; import { Box, Paper, Divider } from "@mui/material"; import { listWebDavBackup } from "@/services/cmds"; dayjs.extend(customParseFormat); const DATE_FORMAT = "YYYY-MM-DD_HH-mm-ss"; const FILENAME_PATTERN = /\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/; export const BackupViewer = forwardRef((props, ref) => { const { t } = useTranslation(); const [open, setOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [backupFiles, setBackupFiles] = useState([]); const [dataSource, setDataSource] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(0); const OS = getSystem(); useImperativeHandle(ref, () => ({ open: () => { setOpen(true); }, close: () => setOpen(false), })); // Handle page change const handleChangePage = useCallback( (_: React.MouseEvent | null, page: number) => { setPage(page); }, [] ); const fetchAndSetBackupFiles = async () => { try { setIsLoading(true); const files = await getAllBackupFiles(); setBackupFiles(files); setTotal(files.length); } catch (error) { console.error(error); // Notice.error(t("Failed to fetch backup files")); } finally { setIsLoading(false); } }; const getAllBackupFiles = async () => { const files = await listWebDavBackup(); return files .map((file) => { const platform = file.filename.split("-")[0]; const fileBackupTimeStr = file.filename.match(FILENAME_PATTERN)!; if (fileBackupTimeStr === null) { return null; } const backupTime = dayjs(fileBackupTimeStr[0], DATE_FORMAT); const allowApply = OS === platform; return { ...file, platform, backup_time: backupTime, allow_apply: allowApply, } as BackupFile; }) .filter((item) => item !== null) .sort((a, b) => (a.backup_time.isAfter(b.backup_time) ? -1 : 1)); }; useEffect(() => { setDataSource( backupFiles.slice( page * DEFAULT_ROWS_PER_PAGE, page * DEFAULT_ROWS_PER_PAGE + DEFAULT_ROWS_PER_PAGE ) ); }, [page, backupFiles]); return ( setOpen(false)} onCancel={() => setOpen(false)} disableOk > { fetchAndSetBackupFiles(); }} onSaveSuccess={async () => { fetchAndSetBackupFiles(); }} onInit={async () => { fetchAndSetBackupFiles(); }} /> ); });