refactor: squash commits

This commit is contained in:
dec0dOS 2021-03-21 22:25:13 +03:00
parent 63ebcb5915
commit 1e6e237aa3
107 changed files with 20077 additions and 0 deletions

View file

@ -0,0 +1,185 @@
import { useState, useEffect, useCallback } from "react";
import { useParams } from "react-router-dom";
import {
Accordion,
AccordionSummary,
AccordionDetails,
Checkbox,
Grid,
Typography,
IconButton,
} from "@material-ui/core";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import RefreshIcon from "@material-ui/icons/Refresh";
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 API from "utils/API";
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper";
function NetworkMembers() {
const { nwid } = useParams();
const [members, setMembers] = useState([]);
const fetchData = useCallback(async () => {
try {
const members = await API.get("network/" + nwid + "/member");
setMembers(members.data);
console.log("Members:", members.data);
} catch (err) {
console.error(err);
}
}, [nwid]);
useEffect(() => {
fetchData();
const timer = setInterval(() => fetchData(), 30000);
return () => clearInterval(timer);
}, [nwid, fetchData]);
const sendReq = async (mid, data) => {
const req = await API.post("/network/" + nwid + "/member/" + mid, data);
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 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 data = setValue({}, key1, key2, value);
sendReq(member["config"]["id"], data);
};
const columns = [
{
id: "auth",
name: "Authorized",
minWidth: "80px",
cell: (row) => (
<Checkbox
checked={row.config.authorized}
color="primary"
onChange={handleChange(row, "config", "authorized", "checkbox")}
/>
),
},
{
id: "address",
name: "Address",
minWidth: "150px",
cell: (row) => (
<Typography variant="body2">{row.config.address}</Typography>
),
},
{
id: "name",
name: "Name/Description",
minWidth: "250px",
cell: (row) => <MemberName member={row} handleChange={handleChange} />,
},
{
id: "ips",
name: "Managed IPs",
minWidth: "220px",
cell: (row) => <ManagedIP member={row} handleChange={handleChange} />,
},
{
***REMOVED***
id: "status",
name: "Peer status",
minWidth: "100px",
cell: (row) =>
row.online ? (
<Typography style={{ color: "#008000" }}>
{"ONLINE (v" +
row.config.vMajor +
"." +
row.config.vMinor +
"." +
row.config.vRev +
")"}
</Typography>
) : (
<Typography color="error">OFFLINE</Typography>
),
},
{
id: "delete",
name: "",
minWidth: "50px",
right: true,
cell: (row) => (
<>
<MemberSettings member={row} handleChange={handleChange} />
<DeleteMember nwid={nwid} mid={row.config.id} callback={fetchData} />
</>
),
},
];
return (
<Accordion defaultExpanded={true}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Members</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid container direction="column" spacing={3}>
<IconButton color="primary" onClick={fetchData}>
<RefreshIcon />
</IconButton>
<Grid container>
{members.length ? (
<DataTable
noHeader={true}
columns={columns}
data={[...members]}
/>
) : (
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justify="center"
style={{
minHeight: "50vh",
}}
>
<Typography variant="h6" style={{ padding: "10%" }}>
No devices have joined this network. Use the app on your
devices to join <b>{nwid}</b>.
</Typography>
</Grid>
)}
</Grid>
<Grid item>
<AddMember nwid={nwid} callback={fetchData} />
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
);
}
export default NetworkMembers;

View file

@ -0,0 +1,55 @@
import { useState } from "react";
import { List, Typography, IconButton, TextField } from "@material-ui/core";
import AddIcon from "@material-ui/icons/Add";
import API from "utils/API";
function AddMember({ nwid, callback }) {
const [member, setMember] = useState("");
const handleInput = (event) => {
setMember(event.target.value);
};
const addMemberReq = async () => {
if (member.length === 10) {
const req = await API.post("/network/" + nwid + "/member/" + member, {
config: { authorized: true },
hidden: false,
});
console.log("Action:", req);
callback();
}
setMember("");
};
return (
<>
<Typography>Manually Add Member</Typography>
<List
disablePadding={true}
style={{
display: "flex",
flexDirection: "row",
}}
>
<TextField
value={member}
onChange={handleInput}
placeholder={"##########"}
/>
<IconButton size="small" color="primary" onClick={addMemberReq}>
<AddIcon
style={{
fontSize: 16,
}}
/>
</IconButton>
</List>
</>
);
}
export default AddMember;

View file

@ -0,0 +1 @@
export { default } from "./AddMember";

View file

@ -0,0 +1,59 @@
import { useState } from "react";
import {
Button,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
IconButton,
} from "@material-ui/core";
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
import API from "utils/API";
function DeleteMember({ nwid, mid, callback }) {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const deleteMemberReq = async () => {
const req = await API.delete("/network/" + nwid + "/member/" + mid);
console.log("Action:", req);
setOpen(false);
callback();
};
return (
<>
<IconButton color="primary" onClick={handleClickOpen}>
<DeleteOutlineIcon color="secondary" style={{ fontSize: 20 }} />
</IconButton>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>
{"Are you sure you want to delete this member?"}
</DialogTitle>
<DialogContent>
<DialogContentText>This action cannot be undone.</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={deleteMemberReq} color="secondary">
Delete
</Button>
</DialogActions>
</Dialog>
</>
);
}
export default DeleteMember;

View file

@ -0,0 +1 @@
export { default } from "./DeleteMember";

View file

@ -0,0 +1,76 @@
import { useState } from "react";
import { Grid, List, TextField, IconButton } from "@material-ui/core";
import AddIcon from "@material-ui/icons/Add";
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
import { validateIP, normilizeIP } from "utils/IP";
function ManagedIP({ member, handleChange }) {
const [ipInput, setIpInput] = useState();
const [normolizedInput, setNormolizedInput] = useState();
const handleInput = (event) => {
const ip = event.target.value;
setIpInput(ip);
if (validateIP(ip)) {
setNormolizedInput(normilizeIP(ip));
}
};
return (
<Grid>
{member.config.ipAssignments.map((value, i) => (
<List
key={i + "_ips"}
disablePadding={true}
style={{ display: "flex", flexDirection: "row" }}
>
<IconButton
size="small"
color="secondary"
onClick={handleChange(
member,
"config",
"ipAssignments",
"arrayDel",
i
)}
>
<DeleteOutlineIcon style={{ fontSize: 14 }} />
</IconButton>
{value}
</List>
))}
<List
disablePadding={true}
style={{
display: "flex",
flexDirection: "row",
}}
>
<IconButton
size="small"
color="primary"
onClick={handleChange(
member,
"config",
"ipAssignments",
"arrayAdd",
normolizedInput
)}
>
<AddIcon
style={{
fontSize: 14,
}}
/>
</IconButton>
<TextField value={ipInput} onChange={handleInput} />
</List>
</Grid>
);
}
export default ManagedIP;

View file

@ -0,0 +1 @@
export { default } from "./ManagedIP";

View file

@ -0,0 +1,28 @@
import { Grid, TextField } from "@material-ui/core";
function MemberName({ member, handleChange }) {
return (
<Grid>
<TextField
value={member.name}
onChange={handleChange(member, "name")}
label="Name"
variant="filled"
InputLabelProps={{
shrink: true,
}}
/>
<TextField
value={member.description}
onChange={handleChange(member, "description")}
label="Description"
variant="filled"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
);
}
export default MemberName;

View file

@ -0,0 +1 @@
export { default } from "./MemberName";

View file

@ -0,0 +1,64 @@
import { useState } from "react";
import {
Checkbox,
Dialog,
DialogTitle,
DialogContent,
Grid,
IconButton,
} from "@material-ui/core";
import BuildIcon from "@material-ui/icons/Build";
function MemberSettings({ member, handleChange }) {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<>
<IconButton color="primary" onClick={handleClickOpen}>
<BuildIcon style={{ fontSize: 20 }} />
</IconButton>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>{"Member " + member.config.id + " settings"}</DialogTitle>
<DialogContent>
<Grid item>
<Checkbox
checked={member["config"]["activeBridge"]}
color="primary"
onChange={handleChange(
member,
"config",
"activeBridge",
"checkbox"
)}
/>
<span>Allow Ethernet Bridging</span>
</Grid>
<Grid item>
<Checkbox
checked={member["config"]["noAutoAssignIps"]}
color="primary"
onChange={handleChange(
member,
"config",
"noAutoAssignIps",
"checkbox"
)}
/>
<span>Do Not Auto-Assign IPs</span>
</Grid>
</DialogContent>
</Dialog>
</>
);
}
export default MemberSettings;

View file

@ -0,0 +1 @@
export { default } from "./MemberSettings";

View file

@ -0,0 +1 @@
export { default } from "./NetworkMembers";