mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	feat(react/settings): port backup DB list
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| import { BackupDatabaseNowResponse } from "@triliumnext/commons"; | import { BackupDatabaseNowResponse, DatabaseBackup } from "@triliumnext/commons"; | ||||||
| import { t } from "../../../services/i18n"; | import { t } from "../../../services/i18n"; | ||||||
| import server from "../../../services/server"; | import server from "../../../services/server"; | ||||||
| import toast from "../../../services/toast"; | import toast from "../../../services/toast"; | ||||||
| @@ -8,12 +8,32 @@ import FormGroup from "../../react/FormGroup"; | |||||||
| import FormText from "../../react/FormText"; | import FormText from "../../react/FormText"; | ||||||
| import { useTriliumOptionBool } from "../../react/hooks"; | import { useTriliumOptionBool } from "../../react/hooks"; | ||||||
| import OptionsSection from "./components/OptionsSection"; | import OptionsSection from "./components/OptionsSection"; | ||||||
|  | import { useCallback, useEffect, useState } from "preact/hooks"; | ||||||
|  | import { formatDateTime } from "../../../utils/formatters"; | ||||||
|  |  | ||||||
| export default function BackupSettings() { | export default function BackupSettings() { | ||||||
|  |     const [ backups, setBackups ] = useState<DatabaseBackup[]>([]); | ||||||
|  |  | ||||||
|  |     const refreshBackups = useCallback(() => { | ||||||
|  |         server.get<DatabaseBackup[]>("database/backups").then((backupFiles) => { | ||||||
|  |             // Sort the backup files by modification date & time in a desceding order | ||||||
|  |             backupFiles.sort((a, b) => { | ||||||
|  |                 if (a.mtime < b.mtime) return 1; | ||||||
|  |                 if (a.mtime > b.mtime) return -1; | ||||||
|  |                 return 0; | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |             setBackups(backupFiles); | ||||||
|  |         }); | ||||||
|  |     }, [ setBackups ]); | ||||||
|  |  | ||||||
|  |     useEffect(refreshBackups, []); | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <> |         <> | ||||||
|             <AutomaticBackup /> |             <AutomaticBackup /> | ||||||
|             <BackupNow /> |             <BackupNow refreshCallback={refreshBackups} /> | ||||||
|  |             <BackupList backups={backups} /> | ||||||
|         </> |         </> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| @@ -50,7 +70,7 @@ export function AutomaticBackup() { | |||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
| export function BackupNow() { | export function BackupNow({ refreshCallback }: { refreshCallback: () => void }) { | ||||||
|     return ( |     return ( | ||||||
|         <OptionsSection title={t("backup.backup_now")}> |         <OptionsSection title={t("backup.backup_now")}> | ||||||
|             <Button |             <Button | ||||||
| @@ -58,8 +78,42 @@ export function BackupNow() { | |||||||
|                 onClick={async () => { |                 onClick={async () => { | ||||||
|                     const { backupFile } = await server.post<BackupDatabaseNowResponse>("database/backup-database"); |                     const { backupFile } = await server.post<BackupDatabaseNowResponse>("database/backup-database"); | ||||||
|                     toast.showMessage(t("backup.database_backed_up_to", { backupFilePath: backupFile }), 10000); |                     toast.showMessage(t("backup.database_backed_up_to", { backupFilePath: backupFile }), 10000); | ||||||
|  |                     refreshCallback(); | ||||||
|                 }} |                 }} | ||||||
|             /> |             /> | ||||||
|         </OptionsSection> |         </OptionsSection> | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function BackupList({ backups }: { backups: DatabaseBackup[] }) { | ||||||
|  |     return ( | ||||||
|  |         <OptionsSection title={t("backup.existing_backups")}> | ||||||
|  |             <table class="table table-stripped"> | ||||||
|  |                 <colgroup> | ||||||
|  |                     <col width="33%" /> | ||||||
|  |                     <col /> | ||||||
|  |                 </colgroup> | ||||||
|  |                 <thead> | ||||||
|  |                     <tr> | ||||||
|  |                         <th>{t("backup.date-and-time")}</th> | ||||||
|  |                         <th>{t("backup.path")}</th> | ||||||
|  |                     </tr> | ||||||
|  |                 </thead> | ||||||
|  |                 <tbody> | ||||||
|  |                     { backups.length > 0 ? ( | ||||||
|  |                         backups.map(({ mtime, filePath }) => ( | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>{mtime ? formatDateTime(mtime) : "-"}</td> | ||||||
|  |                                 <td>{filePath}</td> | ||||||
|  |                             </tr> | ||||||
|  |                         )) | ||||||
|  |                     ) : ( | ||||||
|  |                         <tr> | ||||||
|  |                             <td className="empty-table-placeholder" colspan={2}>{t("backup.no_backup_yet")}</td> | ||||||
|  |                         </tr> | ||||||
|  |                     )} | ||||||
|  |                 </tbody> | ||||||
|  |             </table> | ||||||
|  |         </OptionsSection> | ||||||
|  |     );    | ||||||
|  | } | ||||||
| @@ -9,11 +9,11 @@ import syncMutexService from "./sync_mutex.js"; | |||||||
| import cls from "./cls.js"; | import cls from "./cls.js"; | ||||||
| import sql from "./sql.js"; | import sql from "./sql.js"; | ||||||
| import path from "path"; | import path from "path"; | ||||||
| import type { OptionNames } from "@triliumnext/commons"; | import type { DatabaseBackup, OptionNames } from "@triliumnext/commons"; | ||||||
|  |  | ||||||
| type BackupType = "daily" | "weekly" | "monthly"; | type BackupType = "daily" | "weekly" | "monthly"; | ||||||
|  |  | ||||||
| function getExistingBackups() { | function getExistingBackups(): DatabaseBackup[] { | ||||||
|     if (!fs.existsSync(dataDir.BACKUP_DIR)) { |     if (!fs.existsSync(dataDir.BACKUP_DIR)) { | ||||||
|         return []; |         return []; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -101,3 +101,9 @@ export interface PostTokensResponse { | |||||||
| export interface BackupDatabaseNowResponse { | export interface BackupDatabaseNowResponse { | ||||||
|     backupFile: string; |     backupFile: string; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export interface DatabaseBackup { | ||||||
|  |     fileName: string; | ||||||
|  |     filePath: string; | ||||||
|  |     mtime: Date; | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user