add: filtering table of firewall + InterfaceSelector frontend fixes and improves
This commit is contained in:
@@ -1,25 +1,27 @@
|
||||
import { SegmentedControl, SegmentedControlProps } from "@mantine/core";
|
||||
import { RuleMode } from "./utils";
|
||||
import { RuleMode, Table } from "./utils";
|
||||
import { table } from "console";
|
||||
|
||||
|
||||
|
||||
export const ModeSelector = (props:Omit<SegmentedControlProps, "data">) => (
|
||||
<SegmentedControl
|
||||
export const ModeSelector = (props:Omit<SegmentedControlProps, "data"> & { table: Table }) => {
|
||||
const isFilterTable = props.table == Table.FILTER
|
||||
return <SegmentedControl
|
||||
data={[
|
||||
{
|
||||
value: RuleMode.IN,
|
||||
label: 'IN',
|
||||
label: isFilterTable?'IN':'PREROUTING',
|
||||
},
|
||||
{
|
||||
...(isFilterTable?[{
|
||||
value: RuleMode.FORWARD,
|
||||
label: 'FWD',
|
||||
},
|
||||
}]:[]),
|
||||
{
|
||||
value: RuleMode.OUT,
|
||||
label: 'OUT',
|
||||
label: isFilterTable?'OUT':'POSTROUTING',
|
||||
}
|
||||
]}
|
||||
size={props.size?props.size:"xs"}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -21,6 +21,11 @@ export enum RuleMode {
|
||||
FORWARD = "forward"
|
||||
}
|
||||
|
||||
export enum Table {
|
||||
MANGLE = "mangle",
|
||||
FILTER = "filter",
|
||||
}
|
||||
|
||||
export type Rule = {
|
||||
active: boolean
|
||||
name:string,
|
||||
@@ -33,6 +38,7 @@ export type Rule = {
|
||||
port_dst_to: number,
|
||||
action: ActionType,
|
||||
mode: RuleMode,
|
||||
table: Table
|
||||
}
|
||||
|
||||
export type RuleInfo = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Combobox, TextInput, useCombobox } from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ipInterfacesQuery } from "../js/utils";
|
||||
|
||||
interface ItemProps{
|
||||
@@ -38,7 +38,7 @@ export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames,
|
||||
},
|
||||
});
|
||||
|
||||
const data = [...customIpInterfaces, ...interfaces]
|
||||
const data = [...customIpInterfaces.filter(v => !interfaces.map(v => v.value).includes(v.value)), ...interfaces]
|
||||
const [selectedValue, setSelectedValue] = useState<string | null>(null);
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
@@ -52,12 +52,17 @@ export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames,
|
||||
return a.value.localeCompare(b.value)
|
||||
});
|
||||
|
||||
const options = filteredOptions.map((item) => (
|
||||
const options = filteredOptions.sort( (a, b) => a.value == selectedValue? -1 : b.value == selectedValue? 1: a.value.localeCompare(b.value) ).map((item) => (
|
||||
<Combobox.Option value={item.value} key={item.value}>
|
||||
( <b>{item.netint}</b> ) -{">"} <b>{item.value}</b>
|
||||
( <b>{item.value == selectedValue ? "SELECTED" : item.netint}</b> ) -{">"} <b>{item.value}</b>
|
||||
</Combobox.Option>
|
||||
));
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedValue(data.find((item) => item.value === defaultValue)?.value??null)
|
||||
setSearch(defaultValue??'')
|
||||
}, [])
|
||||
|
||||
return <>
|
||||
<Combobox
|
||||
store={combobox}
|
||||
@@ -81,9 +86,8 @@ export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames,
|
||||
<Combobox.Target>
|
||||
<TextInput
|
||||
style={{width:"100%"}}
|
||||
defaultValue={defaultValue}
|
||||
rightSection={<Combobox.Chevron />}
|
||||
value={value??(defaultValue?undefined:search)}
|
||||
value={value??search}
|
||||
placeholder="10.1.1.1"
|
||||
rightSectionPointerEvents="none"
|
||||
onChange={(event) => {
|
||||
@@ -107,7 +111,7 @@ export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames,
|
||||
</Combobox.Target>
|
||||
|
||||
<Combobox.Dropdown>
|
||||
<Combobox.Options mah={100} style={{ overflowY: 'auto' }}>
|
||||
<Combobox.Options mah={200} style={{ overflowY: 'auto' }}>
|
||||
{options}
|
||||
{(exactOptionMatch==null) && search.trim().length > 0 && (
|
||||
<Combobox.Option value="$create">+ Use this: {search}</Combobox.Option>
|
||||
|
||||
@@ -17,7 +17,7 @@ export const regex_ipv4 = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.
|
||||
export const regex_ipv4_no_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
|
||||
export const regex_port = "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?$"
|
||||
export const regex_range_port = "^(([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(-([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?)?)?$"
|
||||
export const DEV_IP_BACKEND = "127.0.0.1:4444"
|
||||
export const DEV_IP_BACKEND = "198.19.249.69:4444"
|
||||
|
||||
export const queryClient = new QueryClient({ defaultOptions: { queries: {
|
||||
staleTime: Infinity
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ActionIcon, Badge, Box, Button, Divider, LoadingOverlay, Space, Switch, TextInput, Title, Tooltip, useMantineTheme } from "@mantine/core"
|
||||
import { ActionIcon, Badge, Box, Divider, FloatingIndicator, LoadingOverlay, Space, Switch, Table, Tabs, TextInput, Title, Tooltip, useMantineTheme } from "@mantine/core"
|
||||
import { useEffect, useState } from "react";
|
||||
import { BsPlusLg, BsTrashFill } from "react-icons/bs"
|
||||
import { rem } from '@mantine/core';
|
||||
import { ActionType, Protocol, Rule, RuleMode, firewall, firewallRulesQuery } from "../../components/Firewall/utils";
|
||||
import { ActionType, Protocol, Rule, RuleMode, Table as NFTables, firewall, firewallRulesQuery } from "../../components/Firewall/utils";
|
||||
import { errorNotify, getErrorMessage, isMediumScreen, makeid, okNotify } from "../../js/utils";
|
||||
import { useListState, useMediaQuery } from '@mantine/hooks';
|
||||
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
|
||||
@@ -62,6 +62,8 @@ export const Firewall = () => {
|
||||
const {rule_id, ...rest} = v
|
||||
return rest
|
||||
})) || rules.data?.policy != currentPolicy
|
||||
const [selectedTab, setSelectedTab] = useState<NFTables>(NFTables.FILTER)
|
||||
|
||||
|
||||
const enableFirewall = () => {
|
||||
if (valuesChanged){
|
||||
@@ -122,7 +124,8 @@ export const Firewall = () => {
|
||||
port_src_to: 65535,
|
||||
port_dst_to: 8080,
|
||||
action: ActionType.ACCEPT,
|
||||
mode: RuleMode.IN
|
||||
mode: RuleMode.IN,
|
||||
table: selectedTab
|
||||
})
|
||||
}
|
||||
|
||||
@@ -145,7 +148,7 @@ export const Firewall = () => {
|
||||
|
||||
|
||||
const items = state.map((item, index) => (
|
||||
<Draggable key={item.rule_id} index={index} draggableId={item.rule_id}>
|
||||
item.table == selectedTab && <Draggable key={item.rule_id} index={index} draggableId={item.rule_id}>
|
||||
{(provided, snapshot) => {
|
||||
const customInt = [
|
||||
{ value: "0.0.0.0/0", netint: "ANY IPv4", label: "0.0.0.0/0" },
|
||||
@@ -313,6 +316,7 @@ export const Firewall = () => {
|
||||
value={item.mode}
|
||||
onChange={(value)=>{item.mode = value as RuleMode;updateMe()}}
|
||||
style={{width:"100%"}}
|
||||
table={item.table}
|
||||
/>, !isMedium)}
|
||||
<Space h="xs" />
|
||||
{condDiv(<ProtocolSelector
|
||||
@@ -335,7 +339,7 @@ export const Firewall = () => {
|
||||
</Box>
|
||||
}}
|
||||
</Draggable>
|
||||
));
|
||||
)).filter(v => v);
|
||||
|
||||
|
||||
return <>
|
||||
@@ -389,6 +393,18 @@ export const Firewall = () => {
|
||||
</Box>
|
||||
<Space h="xl" />
|
||||
<Divider />
|
||||
<Space h="md"/>
|
||||
<Tabs variant="pills" value={selectedTab} onChange={(v)=>setSelectedTab(v==NFTables.MANGLE?NFTables.MANGLE:NFTables.FILTER)} style={{ display:"flex", justifyContent:"center", alignItems:"center"}}>
|
||||
<Box mr="md">Filtering Table:</Box>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value={NFTables.FILTER}>
|
||||
Filter
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value={NFTables.MANGLE}>
|
||||
Mangle
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
</Tabs>
|
||||
{items.length > 0?<DragDropContext
|
||||
onDragEnd={({ destination, source }) =>
|
||||
handlers.reorder({ from: source.index, to: destination?.index || 0 })
|
||||
|
||||
Reference in New Issue
Block a user