@plutonhq/core-frontend 0.1.24 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/Plan/Backups/Backups.d.ts.map +1 -1
- package/dist-lib/components/Plan/Backups/Backups.js +189 -159
- package/dist-lib/components/Plan/Backups/Backups.js.map +1 -1
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.d.ts +32 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.d.ts.map +1 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.js +252 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewer.js.map +1 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.d.ts +23 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.d.ts.map +1 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.js +72 -0
- package/dist-lib/components/Plan/SnapshotViewer/SnapshotViewerFile.js.map +1 -0
- package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.d.ts.map +1 -1
- package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.js +188 -198
- package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.js.map +1 -1
- package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.module.scss.js +20 -64
- package/dist-lib/components/Restore/RestoreFileSelector/RestoreFileSelector.module.scss.js.map +1 -1
- package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.d.ts.map +1 -1
- package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.js +125 -159
- package/dist-lib/components/Restore/RestoredFileBrowser/RestoredFileBrowser.js.map +1 -1
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowser.module.scss.js +74 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowser.module.scss.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.d.ts +17 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.js +57 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserDirectories.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.d.ts +18 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.js +24 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileList.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.d.ts +18 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.js +37 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserFileRow.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.d.ts +9 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.js +15 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.d.ts +11 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.js +18 -0
- package/dist-lib/components/common/SnapshotBrowser/SnapshotBrowserToolbar.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.d.ts +12 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.js +70 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.d.ts +22 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.js +79 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.d.ts +6 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.d.ts.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.js +18 -0
- package/dist-lib/components/common/SnapshotBrowser/hooks/useSnapshotSort.js.map +1 -0
- package/dist-lib/components/common/SnapshotBrowser/index.d.ts +11 -0
- package/dist-lib/components/common/SnapshotBrowser/index.d.ts.map +1 -0
- package/dist-lib/components/index.d.ts +10 -0
- package/dist-lib/components/index.d.ts.map +1 -1
- package/dist-lib/components.js +152 -132
- package/dist-lib/components.js.map +1 -1
- package/dist-lib/hooks/usePlanSingleActions.d.ts.map +1 -1
- package/dist-lib/hooks/usePlanSingleActions.js +21 -21
- package/dist-lib/hooks/usePlanSingleActions.js.map +1 -1
- package/dist-lib/services/backups.d.ts +4 -0
- package/dist-lib/services/backups.d.ts.map +1 -1
- package/dist-lib/services/backups.js +34 -25
- package/dist-lib/services/backups.js.map +1 -1
- package/dist-lib/services.js +113 -112
- package/dist-lib/styles/core-frontend.css +1 -1
- package/dist-lib/utils/index.d.ts +1 -0
- package/dist-lib/utils/index.d.ts.map +1 -1
- package/dist-lib/utils/snapshotDatabase.d.ts +16 -0
- package/dist-lib/utils/snapshotDatabase.d.ts.map +1 -0
- package/dist-lib/utils/snapshotDatabase.js +105 -0
- package/dist-lib/utils/snapshotDatabase.js.map +1 -0
- package/dist-lib/utils.js +24 -22
- package/dist-lib/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Plan/Backups/Backups.tsx +40 -1
- package/src/components/Plan/SnapshotViewer/SnapshotViewer.tsx +344 -0
- package/src/components/Plan/SnapshotViewer/SnapshotViewerFile.tsx +89 -0
- package/src/components/Restore/RestoreFileSelector/RestoreFileSelector.tsx +82 -145
- package/src/components/Restore/RestoredFileBrowser/RestoredFileBrowser.tsx +71 -156
- package/src/components/common/SnapshotBrowser/SnapshotBrowser.module.scss +376 -0
- package/src/components/common/SnapshotBrowser/SnapshotBrowserDirectories.tsx +84 -0
- package/src/components/common/SnapshotBrowser/SnapshotBrowserFileList.tsx +52 -0
- package/src/components/common/SnapshotBrowser/SnapshotBrowserFileRow.tsx +44 -0
- package/src/components/common/SnapshotBrowser/SnapshotBrowserGoUpRow.tsx +22 -0
- package/src/components/common/SnapshotBrowser/SnapshotBrowserToolbar.tsx +29 -0
- package/src/components/common/SnapshotBrowser/hooks/useSnapshotDatabase.ts +130 -0
- package/src/components/common/SnapshotBrowser/hooks/useSnapshotNavigation.ts +154 -0
- package/src/components/common/SnapshotBrowser/hooks/useSnapshotSort.ts +24 -0
- package/src/components/common/SnapshotBrowser/index.ts +13 -0
- package/src/components/index.ts +13 -0
- package/src/hooks/usePlanSingleActions.tsx +5 -3
- package/src/services/backups.ts +12 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/snapshotDatabase.ts +201 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FileItem } from '../@types/system';
|
|
2
|
+
declare class SnapshotDatabase {
|
|
3
|
+
private backupId;
|
|
4
|
+
private db;
|
|
5
|
+
private isInitialized;
|
|
6
|
+
constructor(backupId: string);
|
|
7
|
+
initialize(): Promise<void>;
|
|
8
|
+
initializeFromFiles(files: FileItem[]): Promise<void>;
|
|
9
|
+
getTopLevelDirectories(maxDepth?: number): Promise<string[]>;
|
|
10
|
+
hasSubdirectories(dirPath: string): Promise<boolean>;
|
|
11
|
+
getSubdirectories(parentPath: string): Promise<string[]>;
|
|
12
|
+
getDirectoryContents(dirPath: string, sortField?: string, sortDirection?: string, searchTerm?: string): Promise<FileItem[]>;
|
|
13
|
+
cleanup(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export default SnapshotDatabase;
|
|
16
|
+
//# sourceMappingURL=snapshotDatabase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotDatabase.d.ts","sourceRoot":"","sources":["../../src/utils/snapshotDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAoB5C,cAAM,gBAAgB;IAIP,OAAO,CAAC,QAAQ;IAH5B,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,aAAa,CAAS;gBAEV,QAAQ,EAAE,MAAM;IAE9B,UAAU;IAaV,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE;IAyCrC,sBAAsB,CAAC,QAAQ,GAAE,MAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoB/D,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBpD,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoBxD,oBAAoB,CACvB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAe,EAC1B,aAAa,GAAE,MAAc,EAC7B,UAAU,GAAE,MAAW,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAkDhB,OAAO;CAKf;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var g = (c, i, e) => i in c ? f(c, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[i] = e;
|
|
3
|
+
var d = (c, i, e) => g(c, typeof i != "symbol" ? i + "" : i, e);
|
|
4
|
+
let h = null;
|
|
5
|
+
async function p() {
|
|
6
|
+
return h || (h = await import("dexie")), h;
|
|
7
|
+
}
|
|
8
|
+
class b {
|
|
9
|
+
constructor(i) {
|
|
10
|
+
d(this, "db", null);
|
|
11
|
+
d(this, "isInitialized", !1);
|
|
12
|
+
this.backupId = i;
|
|
13
|
+
}
|
|
14
|
+
async initialize() {
|
|
15
|
+
if (this.isInitialized) return;
|
|
16
|
+
const { Dexie: i } = await p();
|
|
17
|
+
this.db = new i(`SnapshotDB_${this.backupId}`), this.db.version(1).stores({
|
|
18
|
+
files: "++id, path, parentPath, fileName, isDirFlag, size, modifiedAt, depth"
|
|
19
|
+
}), this.isInitialized = !0;
|
|
20
|
+
}
|
|
21
|
+
async initializeFromFiles(i) {
|
|
22
|
+
await this.initialize(), await this.db.files.clear();
|
|
23
|
+
const e = 1e3, t = [];
|
|
24
|
+
for (let r = 0; r < i.length; r++) {
|
|
25
|
+
const s = i[r], l = s.path.lastIndexOf("/"), a = s.path.substring(0, l), n = (s.name || s.path.split("/").pop() || "").toLowerCase(), o = s.path.split("/").filter(Boolean).length, u = s.isDirectory ? 1 : 0;
|
|
26
|
+
t.push({
|
|
27
|
+
...s,
|
|
28
|
+
parentPath: a,
|
|
29
|
+
fileName: n,
|
|
30
|
+
depth: o,
|
|
31
|
+
isDirFlag: u
|
|
32
|
+
}), t.length >= e && (await this.db.files.bulkAdd(t), t.length = 0);
|
|
33
|
+
}
|
|
34
|
+
t.length > 0 && await this.db.files.bulkAdd(t), console.log("Database initialized with", await this.db.files.count(), "total records");
|
|
35
|
+
}
|
|
36
|
+
// Get only top-level directories (depth <= maxDepth)
|
|
37
|
+
async getTopLevelDirectories(i = 3) {
|
|
38
|
+
this.isInitialized || await this.initialize();
|
|
39
|
+
try {
|
|
40
|
+
const t = (await this.db.files.where("isDirFlag").equals(1).and((r) => r.depth <= i).toArray()).map((r) => r.path);
|
|
41
|
+
return console.log(`getTopLevelDirectories (depth <= ${i}) returning:`, t.length, "directories"), t;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return console.error("Error getting top-level directories:", e), [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Check if a directory has subdirectories
|
|
47
|
+
async hasSubdirectories(i) {
|
|
48
|
+
this.isInitialized || await this.initialize();
|
|
49
|
+
try {
|
|
50
|
+
return await this.db.files.where("parentPath").equals(i).and((t) => t.isDirFlag === 1).count() > 0;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
return console.error("Error checking subdirectories:", e), !1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Get immediate subdirectories of a given directory
|
|
56
|
+
async getSubdirectories(i) {
|
|
57
|
+
this.isInitialized || await this.initialize();
|
|
58
|
+
try {
|
|
59
|
+
const t = (await this.db.files.where("parentPath").equals(i).and((r) => r.isDirFlag === 1).toArray()).map((r) => r.path);
|
|
60
|
+
return console.log(`getSubdirectories for ${i}:`, t.length, "subdirectories"), t;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
return console.error("Error getting subdirectories:", e), [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Get directory contents (files and folders in a specific directory)
|
|
66
|
+
async getDirectoryContents(i, e = "name", t = "asc", r = "") {
|
|
67
|
+
this.isInitialized || await this.initialize();
|
|
68
|
+
try {
|
|
69
|
+
let s;
|
|
70
|
+
if (r.trim()) {
|
|
71
|
+
const l = await this.db.files.where("parentPath").equals(i).toArray(), a = r.toLowerCase();
|
|
72
|
+
s = l.filter((n) => n.fileName.includes(a) || n.path.toLowerCase().includes(a));
|
|
73
|
+
} else
|
|
74
|
+
s = await this.db.files.where("parentPath").equals(i).toArray();
|
|
75
|
+
return s.sort((l, a) => {
|
|
76
|
+
if (l.isDirFlag && !a.isDirFlag) return -1;
|
|
77
|
+
if (!l.isDirFlag && a.isDirFlag) return 1;
|
|
78
|
+
let n, o;
|
|
79
|
+
switch (e) {
|
|
80
|
+
case "name":
|
|
81
|
+
n = l.fileName, o = a.fileName;
|
|
82
|
+
break;
|
|
83
|
+
case "modifiedAt":
|
|
84
|
+
n = new Date(l.modifiedAt).getTime(), o = new Date(a.modifiedAt).getTime();
|
|
85
|
+
break;
|
|
86
|
+
case "size":
|
|
87
|
+
n = l.size || 0, o = a.size || 0;
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
return n < o ? t === "asc" ? -1 : 1 : n > o ? t === "asc" ? 1 : -1 : 0;
|
|
93
|
+
}), s;
|
|
94
|
+
} catch (s) {
|
|
95
|
+
return console.error("Error getting directory contents:", s), [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async cleanup() {
|
|
99
|
+
this.db && await this.db.delete();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export {
|
|
103
|
+
b as default
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=snapshotDatabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotDatabase.js","sources":["../../src/utils/snapshotDatabase.ts"],"sourcesContent":["import { FileItem } from '../@types/system';\r\n\r\n// Lazy load Dexie only when needed\r\nlet DexieModule: any = null;\r\n\r\nasync function loadDexie() {\r\n if (!DexieModule) {\r\n DexieModule = await import('dexie');\r\n }\r\n return DexieModule;\r\n}\r\n\r\ninterface FileRecord extends FileItem {\r\n id?: number;\r\n parentPath: string;\r\n fileName: string;\r\n depth: number;\r\n isDirFlag: number; // 1 for directory, 0 for file\r\n}\r\n\r\nclass SnapshotDatabase {\r\n private db: any = null;\r\n private isInitialized = false;\r\n\r\n constructor(private backupId: string) {}\r\n\r\n async initialize() {\r\n if (this.isInitialized) return;\r\n\r\n const { Dexie } = await loadDexie();\r\n\r\n this.db = new Dexie(`SnapshotDB_${this.backupId}`);\r\n this.db.version(1).stores({\r\n files: '++id, path, parentPath, fileName, isDirFlag, size, modifiedAt, depth',\r\n });\r\n\r\n this.isInitialized = true;\r\n }\r\n\r\n async initializeFromFiles(files: FileItem[]) {\r\n await this.initialize();\r\n\r\n // Clear existing data\r\n await this.db.files.clear();\r\n\r\n // Process and insert files in batches\r\n const batchSize = 1000;\r\n const records: FileRecord[] = [];\r\n\r\n for (let i = 0; i < files.length; i++) {\r\n const file = files[i];\r\n const lastSlashIndex = file.path.lastIndexOf('/');\r\n const parentPath = file.path.substring(0, lastSlashIndex);\r\n const fileName = (file.name || file.path.split('/').pop() || '').toLowerCase();\r\n const depth = file.path.split('/').filter(Boolean).length;\r\n\r\n const isDirFlag = file.isDirectory ? 1 : 0;\r\n\r\n records.push({\r\n ...file,\r\n parentPath,\r\n fileName,\r\n depth,\r\n isDirFlag,\r\n });\r\n\r\n if (records.length >= batchSize) {\r\n await this.db.files.bulkAdd(records);\r\n records.length = 0;\r\n }\r\n }\r\n\r\n if (records.length > 0) {\r\n await this.db.files.bulkAdd(records);\r\n }\r\n\r\n console.log('Database initialized with', await this.db.files.count(), 'total records');\r\n }\r\n\r\n // Get only top-level directories (depth <= maxDepth)\r\n async getTopLevelDirectories(maxDepth: number = 3): Promise<string[]> {\r\n if (!this.isInitialized) await this.initialize();\r\n\r\n try {\r\n const dirRecords = await this.db.files\r\n .where('isDirFlag')\r\n .equals(1)\r\n .and((record: FileRecord) => record.depth <= maxDepth)\r\n .toArray();\r\n\r\n const paths = dirRecords.map((record: FileRecord) => record.path);\r\n console.log(`getTopLevelDirectories (depth <= ${maxDepth}) returning:`, paths.length, 'directories');\r\n return paths;\r\n } catch (error) {\r\n console.error('Error getting top-level directories:', error);\r\n return [];\r\n }\r\n }\r\n\r\n // Check if a directory has subdirectories\r\n async hasSubdirectories(dirPath: string): Promise<boolean> {\r\n if (!this.isInitialized) await this.initialize();\r\n\r\n try {\r\n const count = await this.db.files\r\n .where('parentPath')\r\n .equals(dirPath)\r\n .and((record: FileRecord) => record.isDirFlag === 1)\r\n .count();\r\n\r\n return count > 0;\r\n } catch (error) {\r\n console.error('Error checking subdirectories:', error);\r\n return false;\r\n }\r\n }\r\n\r\n // Get immediate subdirectories of a given directory\r\n async getSubdirectories(parentPath: string): Promise<string[]> {\r\n if (!this.isInitialized) await this.initialize();\r\n\r\n try {\r\n const subdirs = await this.db.files\r\n .where('parentPath')\r\n .equals(parentPath)\r\n .and((record: FileRecord) => record.isDirFlag === 1)\r\n .toArray();\r\n\r\n const paths = subdirs.map((record: FileRecord) => record.path);\r\n console.log(`getSubdirectories for ${parentPath}:`, paths.length, 'subdirectories');\r\n return paths;\r\n } catch (error) {\r\n console.error('Error getting subdirectories:', error);\r\n return [];\r\n }\r\n }\r\n\r\n // Get directory contents (files and folders in a specific directory)\r\n async getDirectoryContents(\r\n dirPath: string,\r\n sortField: string = 'name',\r\n sortDirection: string = 'asc',\r\n searchTerm: string = '',\r\n ): Promise<FileItem[]> {\r\n if (!this.isInitialized) await this.initialize();\r\n\r\n try {\r\n let results: FileRecord[];\r\n\r\n if (searchTerm.trim()) {\r\n const allInDir = await this.db.files.where('parentPath').equals(dirPath).toArray();\r\n const lowerSearch = searchTerm.toLowerCase();\r\n results = allInDir.filter((item: FileRecord) => item.fileName.includes(lowerSearch) || item.path.toLowerCase().includes(lowerSearch));\r\n } else {\r\n results = await this.db.files.where('parentPath').equals(dirPath).toArray();\r\n }\r\n\r\n // Sort results\r\n results.sort((a: FileRecord, b: FileRecord) => {\r\n // Directories first\r\n if (a.isDirFlag && !b.isDirFlag) return -1;\r\n if (!a.isDirFlag && b.isDirFlag) return 1;\r\n\r\n let aVal: any, bVal: any;\r\n switch (sortField) {\r\n case 'name':\r\n aVal = a.fileName;\r\n bVal = b.fileName;\r\n break;\r\n case 'modifiedAt':\r\n aVal = new Date(a.modifiedAt).getTime();\r\n bVal = new Date(b.modifiedAt).getTime();\r\n break;\r\n case 'size':\r\n aVal = a.size || 0;\r\n bVal = b.size || 0;\r\n break;\r\n default:\r\n return 0;\r\n }\r\n\r\n if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1;\r\n if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n\r\n return results;\r\n } catch (error) {\r\n console.error('Error getting directory contents:', error);\r\n return [];\r\n }\r\n }\r\n\r\n async cleanup() {\r\n if (this.db) {\r\n await this.db.delete();\r\n }\r\n }\r\n}\r\n\r\nexport default SnapshotDatabase;\r\n"],"names":["DexieModule","loadDexie","SnapshotDatabase","backupId","__publicField","Dexie","files","batchSize","records","i","file","lastSlashIndex","parentPath","fileName","depth","isDirFlag","maxDepth","paths","record","error","dirPath","sortField","sortDirection","searchTerm","results","allInDir","lowerSearch","item","a","b","aVal","bVal"],"mappings":"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"}
|
package/dist-lib/utils.js
CHANGED
|
@@ -1,48 +1,50 @@
|
|
|
1
|
-
import { API_URL as
|
|
2
|
-
import { calculateDirectorySizes as
|
|
1
|
+
import { API_URL as a, APP_NAME as r, DEFAULT_PLAN_SETTINGS as o, DEV_MODE as s } from "./utils/constants.js";
|
|
2
|
+
import { calculateDirectorySizes as n, clipPath as g, compareVersions as l, formatBytes as m, formatDateTime as p, formatDuration as c, formatNumberToK as P, formatPermissions as f, formatSeconds as A, getAvailableCliApps as d, getLogLevelName as D, getOSIcon as M, getProcessorIcon as S, getUpdateDocLink as E, isMobile as u, isServerEdition as x, isValidEmail as I, isValidURL as N, secondsToMinutes as h, shouldDisplayStorageField as v, sortFileItems as L, timeAgo as T } from "./utils/helpers.js";
|
|
3
3
|
import { isPlanSettingsValid as R, planIntervalAgeName as V, planIntervalName as _ } from "./utils/plans.js";
|
|
4
|
-
import { extractResticData as
|
|
4
|
+
import { extractResticData as U, generateBackupProgressMessage as k, generateMirrorProgressMessage as y, generateRestoreProgressMessage as B, getBackupEventActionMessage as z, getRestoreEventActionMessage as O } from "./utils/progressHelpers.js";
|
|
5
5
|
import { getParentPath as G, getPathSeparator as K, normalizePath as j, splitPath as q } from "./utils/restore.js";
|
|
6
6
|
import { getIconNameForFile as H } from "./utils/getIconNameforFile.js";
|
|
7
|
+
import { default as Q } from "./utils/snapshotDatabase.js";
|
|
7
8
|
export {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
a as API_URL,
|
|
10
|
+
r as APP_NAME,
|
|
10
11
|
o as DEFAULT_PLAN_SETTINGS,
|
|
11
12
|
s as DEV_MODE,
|
|
12
|
-
|
|
13
|
-
n as
|
|
13
|
+
Q as SnapshotDatabase,
|
|
14
|
+
n as calculateDirectorySizes,
|
|
15
|
+
g as clipPath,
|
|
14
16
|
l as compareVersions,
|
|
15
|
-
|
|
17
|
+
U as extractResticData,
|
|
16
18
|
m as formatBytes,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
p as formatDateTime,
|
|
20
|
+
c as formatDuration,
|
|
19
21
|
P as formatNumberToK,
|
|
20
22
|
f as formatPermissions,
|
|
21
23
|
A as formatSeconds,
|
|
22
24
|
k as generateBackupProgressMessage,
|
|
23
25
|
y as generateMirrorProgressMessage,
|
|
24
26
|
B as generateRestoreProgressMessage,
|
|
25
|
-
|
|
27
|
+
d as getAvailableCliApps,
|
|
26
28
|
z as getBackupEventActionMessage,
|
|
27
29
|
H as getIconNameForFile,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
D as getLogLevelName,
|
|
31
|
+
M as getOSIcon,
|
|
30
32
|
G as getParentPath,
|
|
31
33
|
K as getPathSeparator,
|
|
32
|
-
|
|
34
|
+
S as getProcessorIcon,
|
|
33
35
|
O as getRestoreEventActionMessage,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
E as getUpdateDocLink,
|
|
37
|
+
u as isMobile,
|
|
36
38
|
R as isPlanSettingsValid,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
x as isServerEdition,
|
|
40
|
+
I as isValidEmail,
|
|
41
|
+
N as isValidURL,
|
|
40
42
|
j as normalizePath,
|
|
41
43
|
V as planIntervalAgeName,
|
|
42
44
|
_ as planIntervalName,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
h as secondsToMinutes,
|
|
46
|
+
v as shouldDisplayStorageField,
|
|
47
|
+
L as sortFileItems,
|
|
46
48
|
q as splitPath,
|
|
47
49
|
T as timeAgo
|
|
48
50
|
};
|
package/dist-lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,14 @@ import { formatBytes, formatDateTime, formatDuration, formatNumberToK, timeAgo }
|
|
|
6
6
|
import Icon from '../../common/Icon/Icon';
|
|
7
7
|
import classes from './Backups.module.scss';
|
|
8
8
|
import ActionModal from '../../common/ActionModal/ActionModal';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useCancelBackupDownload,
|
|
11
|
+
useDeleteBackup,
|
|
12
|
+
useDownloadBackup,
|
|
13
|
+
useGetBackupDownload,
|
|
14
|
+
useUpdateBackup,
|
|
15
|
+
useBrowseSnapshot,
|
|
16
|
+
} from '../../../services/backups';
|
|
10
17
|
import { useQueryClient } from '@tanstack/react-query';
|
|
11
18
|
import RestoreWizard from '../../Restore/RestoreWizard/RestoreWizard';
|
|
12
19
|
import StatusLabel from '../../common/StatusLabel/StatusLabel';
|
|
@@ -14,6 +21,7 @@ import BackupEvents from '../BackupEvents/BackupEvents';
|
|
|
14
21
|
import Input from '../../common/form/Input/Input';
|
|
15
22
|
import MirrorStatusBadge from '../Mirrors/MirrorStatusBadge';
|
|
16
23
|
import MirrorStorageSelectorModal from '../Mirrors/MirrorStorageSelectorModal';
|
|
24
|
+
import { SidePanel, SnapshotViewer } from '../..';
|
|
17
25
|
|
|
18
26
|
const DownloadLabel = ({ download, downloadBackup }: { download: Backup['download']; downloadBackup: () => void }) => {
|
|
19
27
|
if (download?.status === 'started') {
|
|
@@ -92,6 +100,7 @@ const Backups = ({
|
|
|
92
100
|
const [showDeleteModal, setShowDeleteModal] = useState<Backup | false>(false);
|
|
93
101
|
const [showRestoreModal, setShowRestoreModal] = useState<Backup | false>(false);
|
|
94
102
|
const [showBackupEvents, setShowBackupEvents] = useState<false | string>(false);
|
|
103
|
+
const [showSnapshotViewer, setShowSnapshotViewer] = useState<Backup | false>(false);
|
|
95
104
|
const [showEditModal, setShowEditModal] = useState<Backup | false>(false);
|
|
96
105
|
const [showStorageSelector, setShowStorageSelector] = useState<Backup | false>(false);
|
|
97
106
|
const queryClient = useQueryClient();
|
|
@@ -100,8 +109,11 @@ const Backups = ({
|
|
|
100
109
|
const downloadBackupMutation = useDownloadBackup();
|
|
101
110
|
const cancelDownloadMutation = useCancelBackupDownload();
|
|
102
111
|
const getDownloadMutation = useGetBackupDownload();
|
|
112
|
+
const browseSnapshotMutation = useBrowseSnapshot();
|
|
103
113
|
const isSync = method === 'sync';
|
|
104
114
|
|
|
115
|
+
const snapshotFiles = browseSnapshotMutation.data?.result;
|
|
116
|
+
|
|
105
117
|
console.log('backups :', backups);
|
|
106
118
|
|
|
107
119
|
const removeBackup = (backup: Backup) => {
|
|
@@ -289,6 +301,20 @@ const Backups = ({
|
|
|
289
301
|
<Icon type={isDownloading ? 'close' : 'download'} size={14} /> {isDownloading ? 'Cancel Download' : 'Download'}
|
|
290
302
|
</button>
|
|
291
303
|
)}
|
|
304
|
+
{!isSync && status === 'completed' && active && (
|
|
305
|
+
<button
|
|
306
|
+
onClick={() => {
|
|
307
|
+
toast.promise(browseSnapshotMutation.mutateAsync({ backupId: id }), {
|
|
308
|
+
pending: 'Getting Snapshot Data...',
|
|
309
|
+
error: 'Failed to Get Snapshot Data.',
|
|
310
|
+
});
|
|
311
|
+
setShowSnapOptions(false);
|
|
312
|
+
setShowSnapshotViewer(snapshot);
|
|
313
|
+
}}
|
|
314
|
+
>
|
|
315
|
+
<Icon type="folders" size={14} /> Browse
|
|
316
|
+
</button>
|
|
317
|
+
)}
|
|
292
318
|
{status === 'completed' && active && (
|
|
293
319
|
<button
|
|
294
320
|
className={isDownloading ? 'notAllowed' : ''}
|
|
@@ -414,6 +440,19 @@ const Backups = ({
|
|
|
414
440
|
onClose={() => setShowStorageSelector(false)}
|
|
415
441
|
/>
|
|
416
442
|
)}
|
|
443
|
+
{showSnapshotViewer && showSnapshotViewer.id && browseSnapshotMutation.isSuccess && (
|
|
444
|
+
<SidePanel width="100%" title="Browse Snapshot" icon={<Icon type={'folders'} size={20} />} close={() => setShowSnapshotViewer(false)}>
|
|
445
|
+
<SnapshotViewer
|
|
446
|
+
files={snapshotFiles || []}
|
|
447
|
+
backup={showSnapshotViewer}
|
|
448
|
+
planId={planId}
|
|
449
|
+
isSync={isSync}
|
|
450
|
+
onClose={() => setShowSnapshotViewer(false)}
|
|
451
|
+
mirrors={replicationSettings?.enabled ? showSnapshotViewer.mirrors : undefined}
|
|
452
|
+
primaryStorage={replicationSettings?.enabled ? storage : undefined}
|
|
453
|
+
/>
|
|
454
|
+
</SidePanel>
|
|
455
|
+
)}
|
|
417
456
|
</div>
|
|
418
457
|
);
|
|
419
458
|
};
|