diff --git a/virtweb_frontend/src/App.tsx b/virtweb_frontend/src/App.tsx
index cec2626..00e7089 100644
--- a/virtweb_frontend/src/App.tsx
+++ b/virtweb_frontend/src/App.tsx
@@ -25,8 +25,6 @@ import { OIDCCbRoute } from "./routes/auth/OIDCCbRoute";
import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage";
import { BaseLoginPage } from "./widgets/BaseLoginPage";
import { ViewNetworkRoute } from "./routes/ViewNetworkRoute";
-import { VMXMLRoute } from "./routes/VMXMLRoute";
-import { NetXMLRoute } from "./routes/NetXMLRoute";
import { HomeRoute } from "./routes/HomeRoute";
interface AuthContext {
@@ -57,13 +55,11 @@ export function App() {
} />
} />
} />
- } />
} />
} />
} />
} />
- } />
} />
} />
diff --git a/virtweb_frontend/src/routes/NetXMLRoute.tsx b/virtweb_frontend/src/routes/NetXMLRoute.tsx
deleted file mode 100644
index 97e27a3..0000000
--- a/virtweb_frontend/src/routes/NetXMLRoute.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import ArrowBackIcon from "@mui/icons-material/ArrowBack";
-import { IconButton } from "@mui/material";
-import React from "react";
-import { useParams } from "react-router-dom";
-import { NetworkApi, NetworkInfo, NetworkURL } from "../api/NetworksApi";
-import { AsyncWidget } from "../widgets/AsyncWidget";
-import { RouterLink } from "../widgets/RouterLink";
-import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
-import { XMLWidget } from "../widgets/XMLWidget";
-
-export function NetXMLRoute(): React.ReactElement {
- const { uuid } = useParams();
-
- const [net, setNet] = React.useState();
- const [src, setSrc] = React.useState();
-
- const load = async () => {
- setNet(await NetworkApi.GetSingle(uuid!));
- setSrc(await NetworkApi.GetSingleXML(uuid!));
- };
-
- return (
- }
- />
- );
-}
-
-function XMLRouteInner(p: {
- net: NetworkInfo;
- src: string;
-}): React.ReactElement {
- return (
-
-
-
-
-
- }
- >
-
-
- );
-}
diff --git a/virtweb_frontend/src/routes/VMRoute.tsx b/virtweb_frontend/src/routes/VMRoute.tsx
index 6f31df5..ee997e9 100644
--- a/virtweb_frontend/src/routes/VMRoute.tsx
+++ b/virtweb_frontend/src/routes/VMRoute.tsx
@@ -42,14 +42,6 @@ function VMRouteBody(p: { vm: VMInfo }): React.ReactElement {
-
-
-
-
-
-
-
-
();
- const [src, setSrc] = React.useState();
-
- const load = async () => {
- setVM(await VMApi.GetSingle(uuid!));
- setSrc(await VMApi.GetSingleXML(uuid!));
- };
-
- return (
- }
- />
- );
-}
-
-function XMLRouteInner(p: { vm: VMInfo; src: string }): React.ReactElement {
- return (
-
-
-
-
-
- }
- >
-
-
- );
-}
diff --git a/virtweb_frontend/src/routes/ViewNetworkRoute.tsx b/virtweb_frontend/src/routes/ViewNetworkRoute.tsx
index dbf698f..85d6d19 100644
--- a/virtweb_frontend/src/routes/ViewNetworkRoute.tsx
+++ b/virtweb_frontend/src/routes/ViewNetworkRoute.tsx
@@ -51,14 +51,6 @@ function ViewNetworkRouteInner(p: {
-
-
-
-
-
-
-
-
);
}
+
+export function XMLAsyncWidget(p: {
+ identifier: string;
+ load: () => Promise;
+ errMsg: string;
+}): React.ReactElement {
+ const [src, setSrc] = React.useState();
+
+ const load = async () => {
+ setSrc(await p.load());
+ };
+
+ return (
+ }
+ />
+ );
+}
diff --git a/virtweb_frontend/src/widgets/net/NetworkDetails.tsx b/virtweb_frontend/src/widgets/net/NetworkDetails.tsx
index 8776144..d938e46 100644
--- a/virtweb_frontend/src/widgets/net/NetworkDetails.tsx
+++ b/virtweb_frontend/src/widgets/net/NetworkDetails.tsx
@@ -14,6 +14,7 @@ import { ResAutostartInput } from "../forms/ResAutostartInput";
import { SelectInput } from "../forms/SelectInput";
import { TextInput } from "../forms/TextInput";
import { DHCPHostReservations } from "./DHCPHostReservations";
+import { XMLAsyncWidget } from "../XMLWidget";
interface DetailsProps {
net: NetworkInfo;
@@ -42,6 +43,7 @@ enum NetTab {
General = 0,
IPv4,
IPv6,
+ XML,
Danger,
}
@@ -67,6 +69,11 @@ function NetworkDetailsInner(p: DetailsInnerProps): React.ReactElement {
value: NetTab.IPv6,
visible: p.editable || !!p.net.ip_v6,
},
+ {
+ label: "XML",
+ value: NetTab.XML,
+ visible: !p.editable,
+ },
{
label: "Danger zone",
value: NetTab.Danger,
@@ -79,6 +86,7 @@ function NetworkDetailsInner(p: DetailsInnerProps): React.ReactElement {
{currTab === NetTab.General && }
{currTab === NetTab.IPv4 && }
{currTab === NetTab.IPv6 && }
+ {currTab === NetTab.XML && }
{currTab === NetTab.Danger && }
>
);
@@ -380,6 +388,16 @@ function IPSection(p: {
);
}
+function NetworkDetailsTabXML(p: DetailsInnerProps): React.ReactElement {
+ return (
+ NetworkApi.GetSingleXML(p.net.uuid!)}
+ />
+ );
+}
+
function NetworkDetailsTabDanger(p: DetailsInnerProps): React.ReactElement {
const confirm = useConfirm();
const snackbar = useSnackbar();
diff --git a/virtweb_frontend/src/widgets/vms/VMDetails.tsx b/virtweb_frontend/src/widgets/vms/VMDetails.tsx
index aff3791..e4d247c 100644
--- a/virtweb_frontend/src/widgets/vms/VMDetails.tsx
+++ b/virtweb_frontend/src/widgets/vms/VMDetails.tsx
@@ -21,6 +21,7 @@ import { VMDisksList } from "../forms/VMDisksList";
import { VMNetworksList } from "../forms/VMNetworksList";
import { VMSelectIsoInput } from "../forms/VMSelectIsoInput";
import { VMScreenshot } from "./VMScreenshot";
+import { XMLAsyncWidget } from "../XMLWidget";
interface DetailsProps {
vm: VMInfo;
@@ -68,6 +69,7 @@ enum VMTab {
General = 0,
Storage,
Network,
+ XML,
Danger,
}
@@ -90,6 +92,11 @@ function VMDetailsInner(p: DetailsInnerProps): React.ReactElement {
{ label: "General", value: VMTab.General, visible: true },
{ label: "Storage", value: VMTab.Storage, visible: true },
{ label: "Network", value: VMTab.Network, visible: true },
+ {
+ label: "XML",
+ value: VMTab.XML,
+ visible: !p.editable,
+ },
{
label: "Danger zone",
value: VMTab.Danger,
@@ -102,6 +109,7 @@ function VMDetailsInner(p: DetailsInnerProps): React.ReactElement {
{currTab === VMTab.General && }
{currTab === VMTab.Storage && }
{currTab === VMTab.Network && }
+ {currTab === VMTab.XML && }
{currTab === VMTab.Danger && }
>
);
@@ -293,6 +301,16 @@ function VMDetailsTabNetwork(p: DetailsInnerProps): React.ReactElement {
return ;
}
+function VMDetailsTabXML(p: DetailsInnerProps): React.ReactElement {
+ return (
+ VMApi.GetSingleXML(p.vm.uuid!)}
+ />
+ );
+}
+
function VMDetailsTabDanger(p: DetailsInnerProps): React.ReactElement {
const confirm = useConfirm();
const alert = useAlert();