mirror of
https://github.com/dec0dOS/zero-ui.git
synced 2025-07-10 23:33:03 -07:00
parent
369d96e50a
commit
8f891747d6
7 changed files with 314 additions and 71 deletions
|
@ -1,30 +1,26 @@
|
|||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Checkbox,
|
||||
Grid,
|
||||
Typography,
|
||||
IconButton,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import DataTable from "react-data-table-component";
|
||||
|
||||
import MemberName from "./components/MemberName";
|
||||
import ManagedIP from "./components/ManagedIP";
|
||||
import DeleteMember from "./components/DeleteMember";
|
||||
import MemberSettings from "./components/MemberSettings";
|
||||
import AddMember from "./components/AddMember";
|
||||
|
||||
import { useParams } from "react-router-dom";
|
||||
import API from "utils/API";
|
||||
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper";
|
||||
import AddMember from "./components/AddMember";
|
||||
import DeleteMember from "./components/DeleteMember";
|
||||
import ManagedIP from "./components/ManagedIP";
|
||||
import MemberName from "./components/MemberName";
|
||||
import MemberSettings from "./components/MemberSettings";
|
||||
|
||||
function NetworkMembers() {
|
||||
function NetworkMembers({ network }) {
|
||||
const { nwid } = useParams();
|
||||
const [members, setMembers] = useState([]);
|
||||
|
||||
|
@ -49,27 +45,23 @@ function NetworkMembers() {
|
|||
console.log("Action:", req);
|
||||
};
|
||||
|
||||
const handleChange = (
|
||||
member,
|
||||
key1,
|
||||
key2 = null,
|
||||
mode = "text",
|
||||
id = null
|
||||
) => (event) => {
|
||||
const value = parseValue(event, mode, member, key1, key2, id);
|
||||
const handleChange =
|
||||
(member, key1, key2 = null, mode = "text", id = null) =>
|
||||
(event) => {
|
||||
const value = parseValue(event, mode, member, key1, key2, id);
|
||||
|
||||
const updatedMember = replaceValue({ ...member }, key1, key2, value);
|
||||
const updatedMember = replaceValue({ ...member }, key1, key2, value);
|
||||
|
||||
const index = members.findIndex((item) => {
|
||||
return item["config"]["id"] === member["config"]["id"];
|
||||
});
|
||||
let mutableMembers = [...members];
|
||||
mutableMembers[index] = updatedMember;
|
||||
setMembers(mutableMembers);
|
||||
const index = members.findIndex((item) => {
|
||||
return item["config"]["id"] === member["config"]["id"];
|
||||
});
|
||||
let mutableMembers = [...members];
|
||||
mutableMembers[index] = updatedMember;
|
||||
setMembers(mutableMembers);
|
||||
|
||||
const data = setValue({}, key1, key2, value);
|
||||
sendReq(member["config"]["id"], data);
|
||||
};
|
||||
const data = setValue({}, key1, key2, value);
|
||||
sendReq(member["config"]["id"], data);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
@ -130,7 +122,11 @@ function NetworkMembers() {
|
|||
right: true,
|
||||
cell: (row) => (
|
||||
<>
|
||||
<MemberSettings member={row} handleChange={handleChange} />
|
||||
<MemberSettings
|
||||
member={row}
|
||||
network={network}
|
||||
handleChange={handleChange}
|
||||
/>
|
||||
<DeleteMember nwid={nwid} mid={row.config.id} callback={fetchData} />
|
||||
</>
|
||||
),
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { useState } from "react";
|
||||
|
||||
import {
|
||||
Checkbox,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
FormControlLabel,
|
||||
Grid,
|
||||
IconButton,
|
||||
Paper,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import BuildIcon from "@material-ui/icons/Build";
|
||||
import { useState } from "react";
|
||||
import Tag from "./components/Tag";
|
||||
|
||||
function MemberSettings({ member, handleChange }) {
|
||||
function MemberSettings({ member, network, handleChange }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleClickOpen = () => {
|
||||
|
@ -55,6 +58,65 @@ function MemberSettings({ member, handleChange }) {
|
|||
/>
|
||||
<span>Do Not Auto-Assign IPs</span>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h5">Capabilities</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Paper style={{ padding: 20 }}>
|
||||
{Object.entries(network["capabilitiesByName"]).length === 0
|
||||
? "No capabilities defined"
|
||||
: ""}
|
||||
{Object.entries(network["capabilitiesByName"]).map(
|
||||
([capName, capId]) => (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={member["config"]["capabilities"].includes(
|
||||
capId
|
||||
)}
|
||||
color="primary"
|
||||
onChange={handleChange(
|
||||
member,
|
||||
"config",
|
||||
"capabilities",
|
||||
"capChange",
|
||||
capId
|
||||
)}
|
||||
/>
|
||||
}
|
||||
key={"cap-" + capId}
|
||||
label={capName}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h5">Tags</Typography>
|
||||
</Grid>
|
||||
{Object.entries(network["tagsByName"]).length === 0 ? (
|
||||
<Grid item xs={12}>
|
||||
<Paper style={{ padding: 20 }}>No tags defined</Paper>
|
||||
</Grid>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{Object.entries(network["tagsByName"]).map(
|
||||
([tagName, tagDetail]) => (
|
||||
<Grid item xs={12} sm={6} key={"tag-" + tagName}>
|
||||
<Tag
|
||||
member={member}
|
||||
tagName={tagName}
|
||||
tagDetail={tagDetail}
|
||||
handleChange={handleChange}
|
||||
/>
|
||||
</Grid>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
import {
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
Grid,
|
||||
IconButton,
|
||||
Input,
|
||||
Paper,
|
||||
Select,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebounce } from "react-use";
|
||||
|
||||
function Tag({ member, tagName, tagDetail, handleChange }) {
|
||||
const [tagValue, setTagValue] = useState("");
|
||||
const [tagChangedByUser, setTagChangedByUser] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let tagIndex = member["config"]["tags"].findIndex((item) => {
|
||||
return item[0] === tagDetail["id"];
|
||||
});
|
||||
let value = "";
|
||||
if (tagIndex !== -1) {
|
||||
value = member["config"]["tags"][tagIndex][1];
|
||||
}
|
||||
value = value !== false ? value : "";
|
||||
setTagValue(value);
|
||||
}, [member, tagDetail]);
|
||||
|
||||
useDebounce(
|
||||
async () => {
|
||||
if (tagChangedByUser) {
|
||||
let value = tagValue === "" ? "" : parseInt(tagValue);
|
||||
let event = { target: { value: value } };
|
||||
handleChange(
|
||||
member,
|
||||
"config",
|
||||
"tags",
|
||||
"tagChange",
|
||||
tagDetail["id"]
|
||||
)(event);
|
||||
}
|
||||
setTagChangedByUser(false);
|
||||
},
|
||||
500,
|
||||
[tagValue]
|
||||
);
|
||||
|
||||
const handleSelectChange = (event) => {
|
||||
let newValue = event.target.value;
|
||||
setTagChangedByUser(true);
|
||||
setTagValue(newValue);
|
||||
};
|
||||
|
||||
const handleFlagChange = (value) => (event) => {
|
||||
let newValue;
|
||||
let oldValue;
|
||||
|
||||
if (tagValue === "") {
|
||||
oldValue = 0;
|
||||
} else {
|
||||
oldValue = tagValue;
|
||||
}
|
||||
|
||||
if (event.target.checked) {
|
||||
newValue = oldValue + value;
|
||||
} else {
|
||||
newValue = oldValue - value;
|
||||
}
|
||||
setTagChangedByUser(true);
|
||||
setTagValue(newValue);
|
||||
};
|
||||
|
||||
const handleInputChange = (event) => {
|
||||
let value = event.target.value;
|
||||
if (/^(|0|[1-9]\d*)$/.test(value)) {
|
||||
value = value === "" ? value : parseInt(value);
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
setTagChangedByUser(true);
|
||||
setTagValue(value);
|
||||
};
|
||||
|
||||
const clearTag = (event) => {
|
||||
setTagChangedByUser(true);
|
||||
setTagValue("");
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper style={{ padding: 20 }}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
variant="h5"
|
||||
color={tagValue === "" ? "error" : "primary"}
|
||||
>
|
||||
{tagName}
|
||||
{tagValue === "" ? (
|
||||
""
|
||||
) : (
|
||||
<IconButton aria-label="delete" onClick={clearTag}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item xs={6}>
|
||||
<Select
|
||||
native
|
||||
value={tagValue}
|
||||
onChange={handleSelectChange}
|
||||
displayEmpty
|
||||
style={{ minWidth: 100 }}
|
||||
>
|
||||
<option value="">--</option>
|
||||
{Object.entries(tagDetail["enums"]).map(
|
||||
([enumKey, enumValue]) => (
|
||||
<option key={enumKey} value={enumValue}>
|
||||
{enumKey}
|
||||
</option>
|
||||
)
|
||||
)}
|
||||
{Object.values(tagDetail["enums"]).length === 0 &&
|
||||
tagValue !== "" ? (
|
||||
<option value={tagValue}>(no enums)</option>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{Object.values(tagDetail["enums"]).length !== 0 &&
|
||||
!Object.values(tagDetail["enums"]).includes(tagValue) &&
|
||||
tagValue !== "" ? (
|
||||
<option value={tagValue}>(custom)</option>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Select>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Input value={tagValue} onChange={handleInputChange} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{Object.entries(tagDetail["flags"]).map(([flagKey, flagValue]) => (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={(tagValue & flagValue) === flagValue}
|
||||
onChange={handleFlagChange(flagValue)}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
key={"flag-" + flagKey}
|
||||
label={flagKey}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default Tag;
|
|
@ -0,0 +1 @@
|
|||
export { default } from "./Tag";
|
|
@ -1,28 +1,23 @@
|
|||
import { useState } from "react";
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Button,
|
||||
Divider,
|
||||
Snackbar,
|
||||
Hidden,
|
||||
Grid,
|
||||
Hidden,
|
||||
Snackbar,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
|
||||
import CodeMirror from "@uiw/react-codemirror";
|
||||
import "codemirror/theme/3024-day.css";
|
||||
|
||||
import { compile } from "external/RuleCompiler";
|
||||
|
||||
import debounce from "lodash/debounce";
|
||||
|
||||
import { useState } from "react";
|
||||
import API from "utils/API";
|
||||
|
||||
function NetworkRules({ network }) {
|
||||
function NetworkRules({ network, callback }) {
|
||||
const [editor, setEditor] = useState(null);
|
||||
const [flowData, setFlowData] = useState({
|
||||
rules: [...network.config.rules],
|
||||
|
@ -48,6 +43,9 @@ function NetworkRules({ network }) {
|
|||
const timer = setTimeout(() => {
|
||||
setSnackbarOpen(false);
|
||||
}, 1500);
|
||||
|
||||
callback();
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue