Reorganize networks page
This commit is contained in:
parent
085deff4f7
commit
afe5db1fcd
@ -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<NetworkInfo[] | undefined>();
|
||||
|
||||
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 (
|
||||
<AsyncWidget
|
||||
loadKey={count}
|
||||
load={load}
|
||||
ready={list !== undefined}
|
||||
errMsg="Failed to load the list of networks!"
|
||||
build={() => (
|
||||
<NetworksListRouteInner list={list!} onRequestDelete={requestDelete} />
|
||||
)}
|
||||
build={() => <NetworksListRouteInner list={list!} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function NetworksListRouteInner(p: {
|
||||
list: NetworkInfo[];
|
||||
onRequestDelete: (n: NetworkInfo) => void;
|
||||
}): React.ReactElement {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -130,9 +95,6 @@ function NetworksListRouteInner(p: {
|
||||
<VisibilityIcon />
|
||||
</IconButton>
|
||||
</RouterLink>
|
||||
<IconButton onClick={() => p.onRequestDelete(t)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
@ -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 (
|
||||
<>
|
||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
||||
<Tabs value={currTab} onChange={(_ev, newVal) => setCurrTab(newVal)}>
|
||||
<Tab label="General" tabIndex={VMTab.General} />
|
||||
<Tab label="IPv4" tabIndex={VMTab.IPv4} />
|
||||
<Tab label="IPv6" tabIndex={VMTab.IPv6} />
|
||||
{!p.editable && (
|
||||
<Tab
|
||||
label="Danger zone"
|
||||
style={{ color: "red" }}
|
||||
tabIndex={VMTab.Danger}
|
||||
/>
|
||||
)}
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
{currTab === VMTab.General && <NetworkDetailsTabGeneral {...p} />}
|
||||
{currTab === VMTab.IPv4 && <NetworkDetailsTabIPv4 {...p} />}
|
||||
{currTab === VMTab.IPv6 && <NetworkDetailsTabIPv6 {...p} />}
|
||||
{currTab === VMTab.Danger && <NetworkDetailsTabDanger {...p} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function NetworkDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement {
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
{/* Metadata section */}
|
||||
@ -161,7 +199,13 @@ function NetworkDetailsInner(
|
||||
multiline={true}
|
||||
/>
|
||||
</EditSection>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
function NetworkDetailsTabIPv4(p: DetailsInnerProps): React.ReactElement {
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
<IPSection
|
||||
editable={p.editable}
|
||||
config={p.net.ip_v4}
|
||||
@ -171,7 +215,13 @@ function NetworkDetailsInner(
|
||||
}}
|
||||
version={4}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
function NetworkDetailsTabIPv6(p: DetailsInnerProps): React.ReactElement {
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
<IPSection
|
||||
editable={p.editable}
|
||||
config={p.net.ip_v6}
|
||||
@ -309,3 +359,37 @@ function IPSection(p: {
|
||||
</EditSection>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<Button color="error" onClick={requestDelete}>
|
||||
Delete the network
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user