From afe5db1fcda071dba27bb4d562b538c5d37a23ee Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Tue, 2 Jan 2024 23:40:38 +0100 Subject: [PATCH] Reorganize networks page --- .../src/routes/NetworksListRoute.tsx | 42 +------- .../src/widgets/net/NetworkDetails.tsx | 98 +++++++++++++++++-- 2 files changed, 93 insertions(+), 47 deletions(-) diff --git a/virtweb_frontend/src/routes/NetworksListRoute.tsx b/virtweb_frontend/src/routes/NetworksListRoute.tsx index b780a21..0904049 100644 --- a/virtweb_frontend/src/routes/NetworksListRoute.tsx +++ b/virtweb_frontend/src/routes/NetworksListRoute.tsx @@ -17,66 +17,31 @@ import { NetworkApi, NetworkInfo, NetworkURL } from "../api/NetworksApi"; import { AsyncWidget } from "../widgets/AsyncWidget"; import { RouterLink } from "../widgets/RouterLink"; import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer"; -import { useConfirm } from "../hooks/providers/ConfirmDialogProvider"; -import { useSnackbar } from "../hooks/providers/SnackbarProvider"; -import { useAlert } from "../hooks/providers/AlertDialogProvider"; import { NetworkStatusWidget } from "../widgets/net/NetworkStatusWidget"; import { useNavigate } from "react-router-dom"; export function NetworksListRoute(): React.ReactElement { - const confirm = useConfirm(); - const snackbar = useSnackbar(); - const alert = useAlert(); - const [list, setList] = React.useState(); - const [count, setCount] = React.useState(1); + const [count] = React.useState(1); const load = async () => { setList(await NetworkApi.GetList()); }; - const reload = () => { - setList(undefined); - setCount(count + 1); - }; - - const requestDelete = async (n: NetworkInfo) => { - try { - if ( - !(await confirm( - "Do you really want to delete this network?", - `Delete network ${n.name}`, - "Delete" - )) - ) - return; - - await NetworkApi.Delete(n); - reload(); - snackbar("The network was successfully deleted!"); - } catch (e) { - console.error(e); - alert(`Failed to delete the network!\n${e}`); - } - }; - return ( ( - - )} + build={() => } /> ); } function NetworksListRouteInner(p: { list: NetworkInfo[]; - onRequestDelete: (n: NetworkInfo) => void; }): React.ReactElement { const navigate = useNavigate(); @@ -130,9 +95,6 @@ function NetworksListRouteInner(p: { - p.onRequestDelete(t)}> - - ); diff --git a/virtweb_frontend/src/widgets/net/NetworkDetails.tsx b/virtweb_frontend/src/widgets/net/NetworkDetails.tsx index 1b20276..6d08fc8 100644 --- a/virtweb_frontend/src/widgets/net/NetworkDetails.tsx +++ b/virtweb_frontend/src/widgets/net/NetworkDetails.tsx @@ -1,16 +1,19 @@ -import { Checkbox, Grid, Paper } from "@mui/material"; +import { Box, Button, Checkbox, Grid, Paper, Tab, Tabs } from "@mui/material"; import React from "react"; import { IpConfig, NetworkApi, NetworkInfo } from "../../api/NetworksApi"; import { ServerApi } from "../../api/ServerApi"; +import { useAlert } from "../../hooks/providers/AlertDialogProvider"; +import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider"; +import { useSnackbar } from "../../hooks/providers/SnackbarProvider"; import { AsyncWidget } from "../AsyncWidget"; +import { CheckboxInput } from "../forms/CheckboxInput"; import { EditSection } from "../forms/EditSection"; import { IPInput } from "../forms/IPInput"; +import { ResAutostartInput } from "../forms/ResAutostartInput"; import { SelectInput } from "../forms/SelectInput"; import { TextInput } from "../forms/TextInput"; -import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider"; -import { CheckboxInput } from "../forms/CheckboxInput"; -import { ResAutostartInput } from "../forms/ResAutostartInput"; import { DHCPHostReservations } from "./DHCPHostReservations"; +import { useNavigate } from "react-router-dom"; interface DetailsProps { net: NetworkInfo; @@ -35,9 +38,44 @@ export function NetworkDetails(p: DetailsProps): React.ReactElement { ); } -function NetworkDetailsInner( - p: DetailsProps & { cardsList: string[] } -): React.ReactElement { +enum VMTab { + General = 0, + IPv4, + IPv6, + Danger, +} + +type DetailsInnerProps = DetailsProps & { cardsList: string[] }; + +function NetworkDetailsInner(p: DetailsInnerProps): React.ReactElement { + const [currTab, setCurrTab] = React.useState(VMTab.General); + + return ( + <> + + setCurrTab(newVal)}> + + + + {!p.editable && ( + + )} + + + + {currTab === VMTab.General && } + {currTab === VMTab.IPv4 && } + {currTab === VMTab.IPv6 && } + {currTab === VMTab.Danger && } + + ); +} + +function NetworkDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement { return ( {/* Metadata section */} @@ -161,7 +199,13 @@ function NetworkDetailsInner( multiline={true} /> + + ); +} +function NetworkDetailsTabIPv4(p: DetailsInnerProps): React.ReactElement { + return ( + + + ); +} +function NetworkDetailsTabIPv6(p: DetailsInnerProps): React.ReactElement { + return ( + ); } + +function NetworkDetailsTabDanger(p: DetailsInnerProps): React.ReactElement { + const confirm = useConfirm(); + const snackbar = useSnackbar(); + const alert = useAlert(); + const navigate = useNavigate(); + + const requestDelete = async () => { + try { + if ( + !(await confirm( + "Do you really want to delete this network?", + `Delete network ${p.net.name}`, + "Delete" + )) + ) + return; + + await NetworkApi.Delete(p.net); + + navigate("/net"); + snackbar("The network was successfully deleted!"); + } catch (e) { + console.error(e); + alert(`Failed to delete the network!\n${e}`); + } + }; + + return ( + + ); +}