Can configure network autostart
This commit is contained in:
79
virtweb_frontend/src/widgets/forms/IPInput.tsx
Normal file
79
virtweb_frontend/src/widgets/forms/IPInput.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import { TextInput } from "./TextInput";
|
||||
|
||||
export function IPInput(p: {
|
||||
label: string;
|
||||
editable: boolean;
|
||||
value?: string;
|
||||
onValueChange?: (newVal: string | undefined) => void;
|
||||
version: 4 | 6;
|
||||
}): React.ReactElement {
|
||||
const { onValueChange, ...props } = p;
|
||||
return (
|
||||
<TextInput
|
||||
onValueChange={(v) => {
|
||||
onValueChange?.(p.version === 4 ? sanitizeIpV4(v) : sanitizeIpV6(v));
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function sanitizeIpV4(s: string | undefined): string | undefined {
|
||||
if (s === "" || s === undefined) return s;
|
||||
|
||||
let split = s.split(".");
|
||||
if (split.length > 4) split.splice(4);
|
||||
|
||||
let needAnotherIteration = false;
|
||||
|
||||
const res = split
|
||||
.map((v) => {
|
||||
if (v === "") return "";
|
||||
|
||||
const num = Number(v);
|
||||
if (isNaN(num) || num < 0) return "0";
|
||||
if (num > 255) {
|
||||
needAnotherIteration = true;
|
||||
return v.slice(0, 2) + "." + v.slice(2);
|
||||
}
|
||||
return num.toString();
|
||||
})
|
||||
.join(".");
|
||||
|
||||
return needAnotherIteration ? sanitizeIpV4(res) : res;
|
||||
}
|
||||
|
||||
function sanitizeIpV6(s: string | undefined): string | undefined {
|
||||
if (s === "" || s === undefined) return s;
|
||||
|
||||
const split = s.split(":");
|
||||
if (split.length > 8) split.splice(8);
|
||||
|
||||
let needAnotherIteration = false;
|
||||
|
||||
let res = split
|
||||
.map((e) => {
|
||||
if (e === "") return e;
|
||||
|
||||
const num = parseInt(e, 16);
|
||||
if (isNaN(num)) return "0";
|
||||
|
||||
let s = num.toString(16);
|
||||
if (num > 0xffff) {
|
||||
needAnotherIteration = true;
|
||||
return s.slice(0, 4) + ":" + s.slice(4);
|
||||
}
|
||||
|
||||
return s;
|
||||
})
|
||||
.join(":");
|
||||
|
||||
const firstIndex = res.indexOf("::");
|
||||
let nextIndex = res.lastIndexOf("::");
|
||||
while (nextIndex !== firstIndex) {
|
||||
res = res.slice(0, nextIndex) + res.slice(nextIndex + 1);
|
||||
nextIndex = res.lastIndexOf("::");
|
||||
}
|
||||
|
||||
return needAnotherIteration ? sanitizeIpV6(res) : res;
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
import { Alert, CircularProgress, Typography } from "@mui/material";
|
||||
import { VMApi, VMInfo } from "../../api/VMApi";
|
||||
import { AsyncWidget } from "../AsyncWidget";
|
||||
import React from "react";
|
||||
import { CheckboxInput } from "./CheckboxInput";
|
||||
import { useAlert } from "../../hooks/providers/AlertDialogProvider";
|
||||
import { useSnackbar } from "../../hooks/providers/SnackbarProvider";
|
||||
|
||||
export function VMAutostartInput(p: {
|
||||
export function ResAutostartInput(p: {
|
||||
editable: boolean;
|
||||
vm: VMInfo;
|
||||
checkAutotostart: () => Promise<boolean>;
|
||||
setAutotostart: (enable: boolean) => Promise<void>;
|
||||
ressourceName: string;
|
||||
}): React.ReactElement {
|
||||
const alert = useAlert();
|
||||
const snackbar = useSnackbar();
|
||||
@ -16,25 +17,25 @@ export function VMAutostartInput(p: {
|
||||
const [enabled, setEnabled] = React.useState<boolean | undefined>();
|
||||
|
||||
const load = async () => {
|
||||
setEnabled(await VMApi.IsAutostart(p.vm));
|
||||
setEnabled(await p.checkAutotostart());
|
||||
};
|
||||
|
||||
const update = async (enabled: boolean) => {
|
||||
try {
|
||||
await VMApi.SetAutostart(p.vm, enabled);
|
||||
snackbar("Autostart status successfully updated!");
|
||||
await p.setAutotostart(enabled);
|
||||
snackbar(`Autostart status of ${p.ressourceName} successfully updated!`);
|
||||
setEnabled(enabled);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert("Failed to update autostart status of the VM!");
|
||||
alert(`Failed to update autostart status of ${p.ressourceName}!`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={p.vm.uuid}
|
||||
loadKey={p.ressourceName}
|
||||
load={load}
|
||||
errMsg="Failed to check autostart status of the VM!"
|
||||
errMsg={`Failed to check autostart status of ${p.ressourceName}!`}
|
||||
buildLoading={() => (
|
||||
<Typography>
|
||||
<CircularProgress size={"1rem"} /> Checking for autostart
|
||||
@ -42,27 +43,29 @@ export function VMAutostartInput(p: {
|
||||
)}
|
||||
buildError={(e: string) => <Alert severity="error">{e}</Alert>}
|
||||
build={() => (
|
||||
<VMAutostartInputInner
|
||||
<ResAutostartInputInner
|
||||
editable={p.editable}
|
||||
enabled={enabled!}
|
||||
setEnabled={update}
|
||||
resName={p.ressourceName}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function VMAutostartInputInner(p: {
|
||||
function ResAutostartInputInner(p: {
|
||||
editable: boolean;
|
||||
enabled: boolean;
|
||||
setEnabled: (b: boolean) => void;
|
||||
resName: string;
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<div>
|
||||
<CheckboxInput
|
||||
editable={p.editable}
|
||||
checked={p.enabled}
|
||||
label="Autostart VM"
|
||||
label={`Autostart ${p.resName}`}
|
||||
onValueChange={p.setEnabled}
|
||||
/>
|
||||
</div>
|
@ -16,7 +16,7 @@ export function TextInput(p: {
|
||||
maxRows?: number;
|
||||
type?: React.HTMLInputTypeAttribute;
|
||||
}): React.ReactElement {
|
||||
if (((!p.editable && p.value) ?? "") === "") return <></>;
|
||||
if (!p.editable && (p.value ?? "") === "") return <></>;
|
||||
|
||||
let valueError = undefined;
|
||||
if (p.value && p.value.length > 0) {
|
||||
|
Reference in New Issue
Block a user