diff --git a/src/Admin.js b/src/Admin.js index 8b50bd2..e0d7310 100644 --- a/src/Admin.js +++ b/src/Admin.js @@ -32,6 +32,7 @@ import Download from "./component/Admin/Task/Download"; import Task from "./component/Admin/Task/Task"; import Import from "./component/Admin/File/Import"; import Captcha from "./component/Admin/Setting/Captcha"; +import Node from "./component/Admin/Node/Node"; const useStyles = makeStyles((theme) => ({ root: { @@ -183,6 +184,10 @@ export default function Admin() { + + + + )} /> diff --git a/src/component/Admin/Dashboard.js b/src/component/Admin/Dashboard.js index 484be53..a6b0aa4 100644 --- a/src/component/Admin/Dashboard.js +++ b/src/component/Admin/Dashboard.js @@ -31,6 +31,7 @@ import { SettingsEthernet, Share, Storage, + Contactless, } from "@material-ui/icons"; import ChevronLeftIcon from "@material-ui/icons/ChevronLeft"; import ChevronRightIcon from "@material-ui/icons/ChevronRight"; @@ -232,6 +233,11 @@ const items = [ icon: , path: "policy", }, + { + title: "从机节点", + icon: , + path: "node", + }, { title: "用户组", icon: , diff --git a/src/component/Admin/Node/Node.js b/src/component/Admin/Node/Node.js new file mode 100644 index 0000000..6cfef3a --- /dev/null +++ b/src/component/Admin/Node/Node.js @@ -0,0 +1,237 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import API from "../../../middleware/Api"; +import { useDispatch } from "react-redux"; +import { toggleSnackbar } from "../../../actions"; +import Paper from "@material-ui/core/Paper"; +import Button from "@material-ui/core/Button"; +import TableContainer from "@material-ui/core/TableContainer"; +import Table from "@material-ui/core/Table"; +import TableHead from "@material-ui/core/TableHead"; +import TableRow from "@material-ui/core/TableRow"; +import TableCell from "@material-ui/core/TableCell"; +import TableBody from "@material-ui/core/TableBody"; +import TablePagination from "@material-ui/core/TablePagination"; +import { useHistory } from "react-router"; +import IconButton from "@material-ui/core/IconButton"; +import { Delete, Edit } from "@material-ui/icons"; +import Tooltip from "@material-ui/core/Tooltip"; +import Chip from "@material-ui/core/Chip"; +import classNames from "classnames"; + +const useStyles = makeStyles((theme) => ({ + root: { + [theme.breakpoints.up("md")]: { + marginLeft: 100, + }, + marginBottom: 40, + }, + content: { + padding: theme.spacing(2), + }, + container: { + overflowX: "auto", + }, + tableContainer: { + marginTop: 16, + }, + header: { + display: "flex", + justifyContent: "space-between", + }, + disabledBadge: { + marginLeft: theme.spacing(1), + height: 18, + }, + disabledCell: { + color: theme.palette.text.disabled, + }, +})); + +const columns = [ + { id: "#", label: "#", minWidth: 50 }, + { id: "name", label: "名称", minWidth: 170 }, + { + id: "status", + label: "当前状态", + minWidth: 50, + }, + { + id: "features", + label: "已启用功能", + minWidth: 170, + }, + { + id: "action", + label: "操作", + minWidth: 170, + }, +]; + +export default function Node() { + const classes = useStyles(); + const [nodes, setNodes] = useState([]); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [total, setTotal] = useState(0); + + const history = useHistory(); + + const dispatch = useDispatch(); + const ToggleSnackbar = useCallback( + (vertical, horizontal, msg, color) => + dispatch(toggleSnackbar(vertical, horizontal, msg, color)), + [dispatch] + ); + + const loadList = () => { + API.post("/admin/node/list", { + page: page, + page_size: pageSize, + order_by: "id desc", + }) + .then((response) => { + setNodes(response.data.items); + setTotal(response.data.total); + }) + .catch((error) => { + ToggleSnackbar("top", "right", error.message, "error"); + }); + }; + + useEffect(() => { + loadList(); + }, [page, pageSize]); + + const deletePolicy = (id) => { + API.delete("/admin/group/" + id) + .then(() => { + loadList(); + ToggleSnackbar("top", "right", "用户组已删除", "success"); + }) + .catch((error) => { + ToggleSnackbar("top", "right", error.message, "error"); + }); + }; + + const getStatusBadge = (status) => { + if (status === 1) { + return ( + + ); + } + }; + + const getFeatureBadge = (node) => { + if (node.Aria2Enabled) { + return "0"; + } + }; + + return ( +
+
+ +
+ +
+
+ + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {nodes.map((row) => ( + + {row.ID} + + {row.Name} + {getStatusBadge(row.Status)} + + ... + + {getFeatureBadge(row)} + + + + + + history.push( + "/admin/node/edit/" + + row.ID + ) + } + size={"small"} + > + + + + + + deletePolicy(row.ID) + } + size={"small"} + > + + + + + + ))} + +
+
+ setPage(p + 1)} + onChangeRowsPerPage={(e) => { + setPageSize(e.target.value); + setPage(1); + }} + /> +
+
+ ); +}