Started to create rules editor
This commit is contained in:
		
							
								
								
									
										146
									
								
								virtweb_frontend/src/widgets/forms/NWFilterRules.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								virtweb_frontend/src/widgets/forms/NWFilterRules.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
			
		||||
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
 | 
			
		||||
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
 | 
			
		||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
			
		||||
import {
 | 
			
		||||
  Button,
 | 
			
		||||
  Card,
 | 
			
		||||
  CardActions,
 | 
			
		||||
  CardContent,
 | 
			
		||||
  IconButton,
 | 
			
		||||
} from "@mui/material";
 | 
			
		||||
import { NWFilterRule } from "../../api/NWFilterApi";
 | 
			
		||||
import { EditSection } from "./EditSection";
 | 
			
		||||
import { SelectInput } from "./SelectInput";
 | 
			
		||||
import { TextInput } from "./TextInput";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
 | 
			
		||||
export function NWFilterRules(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  rules: NWFilterRule[];
 | 
			
		||||
  onChange?: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const addRule = () => {
 | 
			
		||||
    p.rules.push({
 | 
			
		||||
      action: "drop",
 | 
			
		||||
      direction: "inout",
 | 
			
		||||
      selectors: [],
 | 
			
		||||
    });
 | 
			
		||||
    p.onChange?.();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const swapRules = (f: number, s: number) => {
 | 
			
		||||
    const swap = p.rules[f];
 | 
			
		||||
    p.rules[f] = p.rules[s];
 | 
			
		||||
    p.rules[s] = swap;
 | 
			
		||||
    p.onChange?.();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const deleteRule = (num: number) => {
 | 
			
		||||
    p.rules.splice(num, 1);
 | 
			
		||||
    p.onChange?.();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <EditSection title="Rules">
 | 
			
		||||
      {p.rules.map((r, n) => (
 | 
			
		||||
        <NWRuleEdit
 | 
			
		||||
          key={n}
 | 
			
		||||
          rule={r}
 | 
			
		||||
          onDelete={() => {
 | 
			
		||||
            deleteRule(n);
 | 
			
		||||
          }}
 | 
			
		||||
          onGoDown={
 | 
			
		||||
            n < p.rules.length - 1 ? () => swapRules(n, n + 1) : undefined
 | 
			
		||||
          }
 | 
			
		||||
          onGoUp={n > 0 ? () => swapRules(n, n - 1) : undefined}
 | 
			
		||||
          {...p}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
 | 
			
		||||
      <div style={{ textAlign: "right" }}>
 | 
			
		||||
        {p.editable && <Button onClick={addRule}>Add a new rule</Button>}
 | 
			
		||||
      </div>
 | 
			
		||||
    </EditSection>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function NWRuleEdit(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  rule: NWFilterRule;
 | 
			
		||||
  onChange?: () => void;
 | 
			
		||||
  onGoUp?: () => void;
 | 
			
		||||
  onGoDown?: () => void;
 | 
			
		||||
  onDelete: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <Card style={{ margin: "30px" }} elevation={3}>
 | 
			
		||||
      <CardContent>
 | 
			
		||||
        <div style={{ display: "flex" }}>
 | 
			
		||||
          <SelectInput
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            label="Action"
 | 
			
		||||
            value={p.rule.action}
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.rule.action = v as any;
 | 
			
		||||
              p.onChange?.();
 | 
			
		||||
            }}
 | 
			
		||||
            options={[
 | 
			
		||||
              { label: "drop", value: "drop" },
 | 
			
		||||
              { label: "reject", value: "reject" },
 | 
			
		||||
              { label: "accept", value: "accept" },
 | 
			
		||||
              { label: "return", value: "return" },
 | 
			
		||||
              { label: "continue", value: "continue" },
 | 
			
		||||
            ]}
 | 
			
		||||
          />
 | 
			
		||||
          <span style={{ width: "20px" }}></span>
 | 
			
		||||
          <SelectInput
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            label="Direction"
 | 
			
		||||
            value={p.rule.direction}
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.rule.direction = v as any;
 | 
			
		||||
              p.onChange?.();
 | 
			
		||||
            }}
 | 
			
		||||
            options={[
 | 
			
		||||
              { label: "in", value: "in" },
 | 
			
		||||
              { label: "out", value: "out" },
 | 
			
		||||
              { label: "inout", value: "inout" },
 | 
			
		||||
            ]}
 | 
			
		||||
          />
 | 
			
		||||
          <span style={{ width: "20px" }}></span>
 | 
			
		||||
          <TextInput
 | 
			
		||||
            label="Priority"
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            value={p.rule.priority?.toString()}
 | 
			
		||||
            type="number"
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.rule.priority = v && v !== "" ? Number(v) : undefined;
 | 
			
		||||
              p.onChange?.();
 | 
			
		||||
            }}
 | 
			
		||||
            size={ServerApi.Config.constraints.nwfilter_priority}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
      </CardContent>
 | 
			
		||||
      <CardActions>
 | 
			
		||||
        {p.editable && (
 | 
			
		||||
          <div style={{ display: "flex", width: "100%" }}>
 | 
			
		||||
            <IconButton color="error" onClick={p.onDelete}>
 | 
			
		||||
              <DeleteIcon />
 | 
			
		||||
            </IconButton>
 | 
			
		||||
            <span style={{ flex: 1 }}></span>
 | 
			
		||||
            {p.onGoUp && (
 | 
			
		||||
              <IconButton onClick={p.onGoUp}>
 | 
			
		||||
                <ArrowUpwardIcon />
 | 
			
		||||
              </IconButton>
 | 
			
		||||
            )}
 | 
			
		||||
            {p.onGoDown && (
 | 
			
		||||
              <IconButton onClick={p.onGoDown}>
 | 
			
		||||
                <ArrowDownwardIcon />
 | 
			
		||||
              </IconButton>
 | 
			
		||||
            )}
 | 
			
		||||
          </div>
 | 
			
		||||
        )}
 | 
			
		||||
      </CardActions>
 | 
			
		||||
    </Card>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -17,6 +17,7 @@ import { TextInput } from "../forms/TextInput";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import { SelectInput } from "../forms/SelectInput";
 | 
			
		||||
import { NWFSelectReferencedFilters } from "../forms/NWFSelectReferencedFilters";
 | 
			
		||||
import { NWFilterRules } from "../forms/NWFilterRules";
 | 
			
		||||
 | 
			
		||||
interface DetailsProps {
 | 
			
		||||
  nwfilter: NWFilter;
 | 
			
		||||
@@ -159,6 +160,18 @@ function NetworkFilterDetailsTabGeneral(
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function NetworkFilterDetailsTabRules(
 | 
			
		||||
  p: InnerDetailsProps
 | 
			
		||||
): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <NWFilterRules
 | 
			
		||||
      editable={p.editable}
 | 
			
		||||
      rules={p.nwfilter.rules}
 | 
			
		||||
      onChange={p.onChange}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function NetworkFilterDetailsTabXML(p: InnerDetailsProps): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <XMLAsyncWidget
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user