Builded new structure.

Now with remote setup and management Server
more than one Node can be connected
added user auth
This commit is contained in:
Philipp
2026-05-21 09:51:07 +02:00
parent 4c98d14352
commit aae54167a1
25 changed files with 1942 additions and 52 deletions
+7 -6
View File
@@ -16,14 +16,14 @@ export function VMDetail({ jobs, onBack, onChanged, vm }) {
const [busy, setBusy] = useState(false);
const [error, setError] = useState('');
const vmJobs = useMemo(() => jobs.filter((job) => job.vmName === vm.name), [jobs, vm.name]);
const vmJobs = useMemo(() => jobs.filter((job) => job.vmName === vm.name && job.nodeId === vm.nodeId), [jobs, vm.name, vm.nodeId]);
const visibleJob = vmJobs.find((job) => ['queued', 'running'].includes(job.status)) || vmJobs[0] || null;
const latestSnapshot = snapshots[0]?.time;
async function loadSnapshots() {
setError('');
try {
const result = await api.get(`/snapshots/${encodeURIComponent(vm.name)}`);
const result = await api.get(`/snapshots/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`);
setSnapshots(result.data);
} catch (requestError) {
setError(errorMessage(requestError));
@@ -32,13 +32,13 @@ export function VMDetail({ jobs, onBack, onChanged, vm }) {
useEffect(() => {
loadSnapshots();
}, [vm.name]);
}, [vm.name, vm.nodeId]);
async function createBackup() {
setBusy(true);
setError('');
try {
await api.post(`/backup/${encodeURIComponent(vm.name)}`);
await api.post(`/backup/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`);
await onChanged();
} catch (requestError) {
setError(errorMessage(requestError));
@@ -51,7 +51,7 @@ export function VMDetail({ jobs, onBack, onChanged, vm }) {
setBusy(true);
setError('');
try {
await api.post(`/restore/${encodeURIComponent(vm.name)}`, {
await api.post(`/restore/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`, {
snapshotId: selectedSnapshot.id,
confirmVmName: confirmText,
});
@@ -71,7 +71,7 @@ export function VMDetail({ jobs, onBack, onChanged, vm }) {
setSnapshotFilesLoading(true);
setError('');
try {
const result = await api.get(`/snapshots/${encodeURIComponent(vm.name)}/${encodeURIComponent(snapshot.id)}/files`);
const result = await api.get(`/snapshots/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}/${encodeURIComponent(snapshot.id)}/files`);
setSnapshotFiles(result.data);
} catch (requestError) {
setError(errorMessage(requestError));
@@ -92,6 +92,7 @@ export function VMDetail({ jobs, onBack, onChanged, vm }) {
<h1 className="text-2xl font-semibold text-zinc-100">{vm.name}</h1>
<span className="rounded-md border border-zinc-800 px-2 py-1 text-xs text-zinc-300">{vm.status || 'Unknown'}</span>
</div>
<p className="mt-2 text-sm text-zinc-500">Node: {vm.nodeName || '-'}</p>
<p className="mt-2 text-sm text-zinc-500">Latest snapshot: {latestSnapshot ? formatTime(latestSnapshot) : 'None'}</p>
</div>
<div className="flex gap-2">