Can define network filters
This commit is contained in:
@ -5,7 +5,7 @@ import { LenConstraint } from "../../api/ServerApi";
|
||||
* Couple / Member property edition
|
||||
*/
|
||||
export function TextInput(p: {
|
||||
label: string;
|
||||
label?: string;
|
||||
editable: boolean;
|
||||
value?: string;
|
||||
onValueChange?: (newVal: string | undefined) => void;
|
||||
@ -15,6 +15,7 @@ export function TextInput(p: {
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
type?: React.HTMLInputTypeAttribute;
|
||||
style?: React.CSSProperties;
|
||||
}): React.ReactElement {
|
||||
if (!p.editable && (p.value ?? "") === "") return <></>;
|
||||
|
||||
@ -48,7 +49,7 @@ export function TextInput(p: {
|
||||
type: p.type,
|
||||
}}
|
||||
variant={"standard"}
|
||||
style={{ width: "100%", marginBottom: "15px" }}
|
||||
style={p.style ?? { width: "100%", marginBottom: "15px" }}
|
||||
multiline={p.multiline}
|
||||
minRows={p.minRows}
|
||||
maxRows={p.maxRows}
|
||||
|
@ -0,0 +1,97 @@
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import { VMNetInterfaceFilter } from "../../api/VMApi";
|
||||
import { TextInput } from "./TextInput";
|
||||
|
||||
export function VMNetworkFilterParameters(p: {
|
||||
editable: boolean;
|
||||
filterref: VMNetInterfaceFilter;
|
||||
onChange?: () => void;
|
||||
}): React.ReactElement {
|
||||
if (!p.editable && p.filterref.parameters.length === 0) return <></>;
|
||||
|
||||
const addParameter = () => {
|
||||
p.filterref.parameters.push({ name: "", value: "" });
|
||||
p.onChange?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{p.filterref.parameters.length > 0 && (
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="nwfilter parameters">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Name</TableCell>
|
||||
<TableCell>Value</TableCell>
|
||||
{p.editable && <TableCell></TableCell>}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{p.filterref.parameters.map((row, index) => (
|
||||
<TableRow
|
||||
key={index}
|
||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
||||
>
|
||||
<TableCell
|
||||
component="th"
|
||||
scope="row"
|
||||
style={{ padding: "0px 5px" }}
|
||||
>
|
||||
<TextInput
|
||||
editable={p.editable}
|
||||
value={row.name}
|
||||
onValueChange={(v) => {
|
||||
row.name = v ?? "";
|
||||
p.onChange?.();
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell scope="row" style={{ padding: "0px 5px" }}>
|
||||
<TextInput
|
||||
editable={p.editable}
|
||||
value={row.value}
|
||||
onValueChange={(v) => {
|
||||
row.value = v ?? "";
|
||||
p.onChange?.();
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
{p.editable && (
|
||||
<TableCell style={{ padding: "0px" }}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
p.filterref.parameters.splice(index, 1);
|
||||
p.onChange?.();
|
||||
}}
|
||||
>
|
||||
<Tooltip title="Remove parameter">
|
||||
<DeleteIcon />
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)}
|
||||
|
||||
{p.editable && (
|
||||
<Button onClick={addParameter}>Add a filter ref parameter</Button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -10,19 +10,22 @@ import {
|
||||
ListItemText,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import { NWFilter } from "../../api/NWFilterApi";
|
||||
import { NetworkInfo } from "../../api/NetworksApi";
|
||||
import { ServerApi } from "../../api/ServerApi";
|
||||
import { VMInfo, VMNetInterface } from "../../api/VMApi";
|
||||
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
|
||||
import { SelectInput } from "./SelectInput";
|
||||
import { NetworkInfo } from "../../api/NetworksApi";
|
||||
import { randomMacAddress } from "../../utils/RandUtils";
|
||||
import { ServerApi } from "../../api/ServerApi";
|
||||
import { MACInput } from "./MACInput";
|
||||
import { SelectInput } from "./SelectInput";
|
||||
import { VMNetworkFilterParameters } from "./VMNetworkFilterParameters";
|
||||
|
||||
export function VMNetworksList(p: {
|
||||
vm: VMInfo;
|
||||
onChange?: () => void;
|
||||
editable: boolean;
|
||||
networksList: NetworkInfo[];
|
||||
networkFiltersList: NWFilter[];
|
||||
}): React.ReactElement {
|
||||
const addNew = () => {
|
||||
p.vm.networks.push({
|
||||
@ -60,6 +63,7 @@ function NetworkInfoWidget(p: {
|
||||
onChange?: () => void;
|
||||
removeFromList: () => void;
|
||||
networksList: NetworkInfo[];
|
||||
networkFiltersList: NWFilter[];
|
||||
}): React.ReactElement {
|
||||
const confirm = useConfirm();
|
||||
const deleteNetwork = async () => {
|
||||
@ -160,6 +164,42 @@ function NetworkInfoWidget(p: {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Network Filter */}
|
||||
<SelectInput
|
||||
editable={p.editable}
|
||||
label="Network filter"
|
||||
value={p.network.nwfilterref?.name}
|
||||
onValueChange={(v) => {
|
||||
if (v && !p.network.nwfilterref) {
|
||||
p.network.nwfilterref = { name: v, parameters: [] };
|
||||
} else if (v) {
|
||||
p.network.nwfilterref!.name = v;
|
||||
} else {
|
||||
p.network.nwfilterref = undefined;
|
||||
}
|
||||
p.onChange?.();
|
||||
}}
|
||||
options={[
|
||||
{ label: "No network filer", value: undefined },
|
||||
...p.networkFiltersList.map((v) => {
|
||||
return {
|
||||
value: v.name,
|
||||
label: `${v.name} (${v.chain?.protocol ?? "unspecified"})`,
|
||||
description: `${v.rules.length} rules - ${v.join_filters.length} joint filters`,
|
||||
};
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
|
||||
{p.network.nwfilterref && (
|
||||
<div style={{ margin: "10px" }}>
|
||||
<VMNetworkFilterParameters
|
||||
filterref={p.network.nwfilterref}
|
||||
{...p}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -15,6 +15,7 @@ import { VMScreenshot } from "./VMScreenshot";
|
||||
import { ResAutostartInput } from "../forms/ResAutostartInput";
|
||||
import { VMNetworksList } from "../forms/VMNetworksList";
|
||||
import { NetworkApi, NetworkInfo } from "../../api/NetworksApi";
|
||||
import { NWFilterApi, NWFilter } from "../../api/NWFilterApi";
|
||||
|
||||
interface DetailsProps {
|
||||
vm: VMInfo;
|
||||
@ -29,11 +30,15 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
|
||||
number[] | any
|
||||
>();
|
||||
const [networksList, setNetworksList] = React.useState<NetworkInfo[] | any>();
|
||||
const [networkFiltersList, setNetworkFiltersList] = React.useState<
|
||||
NWFilter[] | any
|
||||
>();
|
||||
|
||||
const load = async () => {
|
||||
setIsoList(await IsoFilesApi.GetList());
|
||||
setVCPUCombinations(await ServerApi.NumberVCPUs());
|
||||
setNetworksList(await NetworkApi.GetList());
|
||||
setNetworkFiltersList(await NWFilterApi.GetList());
|
||||
};
|
||||
|
||||
return (
|
||||
@ -46,6 +51,7 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
|
||||
isoList={isoList}
|
||||
vcpuCombinations={vcpuCombinations}
|
||||
networksList={networksList}
|
||||
networkFiltersList={networkFiltersList}
|
||||
{...p}
|
||||
/>
|
||||
)}
|
||||
@ -58,6 +64,7 @@ function VMDetailsInner(
|
||||
isoList: IsoFile[];
|
||||
vcpuCombinations: number[];
|
||||
networksList: NetworkInfo[];
|
||||
networkFiltersList: NWFilter[];
|
||||
}
|
||||
): React.ReactElement {
|
||||
return (
|
||||
|
Reference in New Issue
Block a user