Improve select network filter input
This commit is contained in:
parent
ed48b22f7f
commit
fdd005a3ec
@ -1,5 +1,6 @@
|
||||
import { Autocomplete, TextField } from "@mui/material";
|
||||
import { NWFilter } from "../../api/NWFilterApi";
|
||||
import { SelectInput } from "./SelectInput";
|
||||
import { NWFilterItem } from "../nwfilter/NWFilterItem";
|
||||
|
||||
export function NWFilterSelectInput(p: {
|
||||
editable: boolean;
|
||||
@ -9,24 +10,32 @@ export function NWFilterSelectInput(p: {
|
||||
onChange?: (name?: string) => void;
|
||||
canBeNull: boolean;
|
||||
}): React.ReactElement {
|
||||
const selectedValue = p.nwfilters.find((o) => o.name === p.value);
|
||||
if (!p.editable && !selectedValue) return <></>;
|
||||
|
||||
if (selectedValue)
|
||||
return (
|
||||
<NWFilterItem
|
||||
value={selectedValue}
|
||||
onDelete={p.editable ? () => p.onChange?.(undefined) : undefined}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectInput
|
||||
editable={p.editable}
|
||||
label={p.label ?? "Network filter"}
|
||||
value={p.value}
|
||||
onValueChange={(v) => p.onChange?.(v)}
|
||||
options={[
|
||||
...(p.canBeNull
|
||||
? [{ label: "No network filer", value: undefined }]
|
||||
: []),
|
||||
...p.nwfilters.map((v) => {
|
||||
return {
|
||||
value: v.name,
|
||||
label: `${v.name} (${v.chain?.protocol ?? "unspecified"})`,
|
||||
description: `${v.rules.length} rules - ${v.join_filters.length} joint filters`,
|
||||
};
|
||||
}),
|
||||
]}
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
options={[...(p.canBeNull ? [undefined] : []), ...p.nwfilters]}
|
||||
getOptionLabel={(o) => o?.name ?? "Unspecified"}
|
||||
value={selectedValue}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} variant="standard" label={p.label} />
|
||||
)}
|
||||
renderOption={(_props, option, _state) => (
|
||||
<NWFilterItem
|
||||
onClick={() => p.onChange?.(option?.name)}
|
||||
value={option}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ import { ServerApi } from "../../api/ServerApi";
|
||||
import { VMInfo, VMNetInterface } from "../../api/VMApi";
|
||||
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
|
||||
import { randomMacAddress } from "../../utils/RandUtils";
|
||||
import { EditSection } from "./EditSection";
|
||||
import { MACInput } from "./MACInput";
|
||||
import { NWFilterSelectInput } from "./NWFilterSelectInput";
|
||||
import { SelectInput } from "./SelectInput";
|
||||
import { VMNetworkFilterParameters } from "./VMNetworkFilterParameters";
|
||||
import { EditSection } from "./EditSection";
|
||||
import { NWFilterSelectInput } from "./NWFilterSelectInput";
|
||||
|
||||
export function VMNetworksList(p: {
|
||||
vm: VMInfo;
|
||||
|
63
virtweb_frontend/src/widgets/nwfilter/NWFilterItem.tsx
Normal file
63
virtweb_frontend/src/widgets/nwfilter/NWFilterItem.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { mdiSecurityNetwork } from "@mdi/js";
|
||||
import Icon from "@mdi/react";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
IconButton,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
} from "@mui/material";
|
||||
import { NWFilter } from "../../api/NWFilterApi";
|
||||
|
||||
export function NWFilterItem(p: {
|
||||
value?: NWFilter;
|
||||
onClick?: () => void;
|
||||
dense?: boolean;
|
||||
onDelete?: () => void;
|
||||
}): React.ReactElement {
|
||||
const inner = (
|
||||
<>
|
||||
{" "}
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<Icon path={mdiSecurityNetwork} />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={
|
||||
p.value
|
||||
? `${p.value.name} (${p.value.chain?.protocol ?? "unspecified"})`
|
||||
: "Unspecified"
|
||||
}
|
||||
secondary={
|
||||
p.value &&
|
||||
`${p.value.rules.length} rules - ${p.value.join_filters.length} joint filters`
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
if (p.onClick)
|
||||
return (
|
||||
<ListItemButton onClick={p.onClick} dense={p.dense}>
|
||||
{inner}
|
||||
</ListItemButton>
|
||||
);
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
secondaryAction={
|
||||
p.onDelete ? (
|
||||
<IconButton onClick={p.onDelete}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{inner}
|
||||
</ListItem>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user