diff --git a/package-lock.json b/package-lock.json index 1730e9e..9443500 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", "react-scripts": "^5.0.0", + "react-table": "^7.7.0", "tailwindcss": "^3.0.23", "web-vitals": "^0.2.4" }, @@ -13214,6 +13215,18 @@ } } }, + "node_modules/react-table": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz", + "integrity": "sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17.0.0-0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -25692,6 +25705,12 @@ "workbox-webpack-plugin": "^6.4.1" } }, + "react-table": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz", + "integrity": "sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==", + "requires": {} + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", diff --git a/package.json b/package.json index 2670b83..85a234b 100644 --- a/package.json +++ b/package.json @@ -5,22 +5,23 @@ "dependencies": { "@auth0/auth0-react": "^1.6.0", "@headlessui/react": "^1.5.0", + "@heroicons/react": "^1.0.4", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", + "autoprefixer": "^10.4.4", + "heroicons": "^1.0.6", "highlight.js": "^11.2.0", "history": "^5.0.1", + "postcss": "^8.4.12", "prop-types": "^15.7.2", "react": "^17.0.1", "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", "react-scripts": "^5.0.0", - "web-vitals": "^0.2.4", - "@heroicons/react": "^1.0.4", - "autoprefixer": "^10.4.4", - "heroicons": "^1.0.6", - "postcss": "^8.4.12", - "tailwindcss": "^3.0.23" + "react-table": "^7.7.0", + "tailwindcss": "^3.0.23", + "web-vitals": "^0.2.4" }, "scripts": { "start": "react-scripts start", @@ -45,8 +46,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "devDependencies": { - } } diff --git a/src/views/Peers.js b/src/views/Peers.js index d79d107..514fd0c 100644 --- a/src/views/Peers.js +++ b/src/views/Peers.js @@ -1,248 +1,511 @@ -import React, {useEffect, useState} from "react"; -import {useAuth0, withAuthenticationRequired} from "@auth0/auth0-react"; -import Loading from "../components/Loading"; -import {deletePeer, getPeers} from "../api/ManagementAPI"; -import {timeAgo} from "../utils/common"; -import EditButton from "../components/EditButton"; +import { useAuth0, withAuthenticationRequired } from "@auth0/auth0-react"; +import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid"; +import React, { useEffect, useState } from "react"; +// import PaginatedPeersList from "../components/PaginatedPeersList" +import { Link } from "react-router-dom"; +import { usePagination, useTable } from "react-table"; +import { deletePeer, getPeers } from "../api/ManagementAPI"; import CopyText from "../components/CopyText"; import DeleteModal from "../components/DeleteDialog"; +import EditButton from "../components/EditButton"; import EmptyPeersPanel from "../components/EmptyPeers"; -import PaginatedPeersList from "../components/PaginatedPeersList" -import {Link} from "react-router-dom"; +import Loading from "../components/Loading"; +import { timeAgo } from "../utils/common"; export const Peers = () => { - const [peers, setPeers] = useState([]); - const [empty, setEmpty] = useState(true) - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [showDeleteDialog, setShowDeleteDialog] = useState(false); - const [peerToDelete, setPeerToDelete] = useState(null); - const [deleteDialogText, setDeleteDialogText] = useState(""); - const [deleteDialogTitle, setDeleteDialogTitle] = useState(""); + const [peers, setPeers] = useState([]); + const [peersBackUp, setPeersBackUp] = useState([]); + const [empty, setEmpty] = useState(true); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [peerToDelete, setPeerToDelete] = useState(null); + const [deleteDialogText, setDeleteDialogText] = useState(""); + const [deleteDialogTitle, setDeleteDialogTitle] = useState(""); - const {getAccessTokenSilently} = useAuth0(); + const { getAccessTokenSilently } = useAuth0(); - const handleError = (error) => { - console.error("Error to fetch data:", error); - setLoading(false); - setError(error); - }; + const handleError = (error) => { + console.error("Error to fetch data:", error); + setLoading(false); + setError(error); + }; + // Add React Table + const data = React.useMemo(() => peers, [peers]); - const formatOS = (os) => { - if (os.startsWith("windows 10")) { - return "Windows 10" - } + const columns = React.useMemo( + () => [ + { + Header: "Name", + accessor: "Name", + }, + { + Header: "IP", + accessor: "IP", + }, + { + Header: "Status", + accessor: "Connected", + }, + { + Header: "Last Seen", + accessor: "LastSeen", + }, + { + Header: "OS", + accessor: "OS", + }, + { + Header: "Version", + accessor: "Version", + }, + ], + [] + ); + const td_class_name = + "whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6"; + const td_class_other = "whitespace-nowrap px-3 py-4 text-sm text-gray-500"; - if (os.startsWith("Darwin")) { - return os.replace("Darwin", "MacOS") - } - - return os - } - - //called when user clicks on table row menu item - const handleRowMenuClick = (action, peer) => { - if (action === "Delete") { - setPeerToDelete(peer); - setDeleteDialogText( - "Are you sure you want to delete peer from your account?" - ); - setDeleteDialogTitle('Delete peer "' + peer.Name + '"'); - setShowDeleteDialog(true); - } - }; - - const showAll = () => { - const showAllBtn = document.getElementById("btn-show-all"); - const showOnlineBtn = document.getElementById("btn-show-online"); - - showAllBtn.classList.add('ring-1', 'ring-indigo-500', 'border-indigo-500', 'outline-none'); - showOnlineBtn.classList.remove('ring-1', 'ring-indigo-500', 'border-indigo-500', 'outline-none'); - refresh(null) - } - - - const showConnected = () => { - const showAllBtn = document.getElementById("btn-show-all"); - const showOnlineBtn = document.getElementById("btn-show-online"); - - showOnlineBtn.classList.add('ring-1', 'ring-indigo-500', 'border-indigo-500', 'outline-none'); - showAllBtn.classList.remove('ring-1', 'ring-indigo-500', 'border-indigo-500', 'outline-none'); - - refresh(function (peers) { - return peers.filter(peer => { - return peer.Connected - }) - }) - } - - const refresh = (filter) => { - getPeers(getAccessTokenSilently) - .then((responseData) => - responseData.sort((a, b) => (a.Name > b.Name ? 1 : -1)) - ) - .then(list => { - setEmpty(list.length === 0) - return list - }) - .then((sorted) => { - return filter != null ? filter(sorted) : sorted - }) - .then((filtered) => { - setPeers(filtered) - }) - .then(() => setLoading(false)) - .catch((error) => handleError(error)); - }; - - // after user confirms (or not) deletion of the peer - const handleDeleteConfirmation = (confirmed) => { - setShowDeleteDialog(false); - if (confirmed) { - deletePeer(getAccessTokenSilently, peerToDelete.IP) - .then(() => setPeerToDelete(null)) - .then(() => refresh(null)) - .catch((error) => { - setPeerToDelete(null); - console.log(error); - }); - } else { - setPeerToDelete(null); - } - }; - - useEffect(() => { - refresh(null); - }, [getAccessTokenSilently]); - - const PeerRow = (peer) => { - return ( -
- A list of all the machines in your account including their name, IP and status. -
-+ A list of all the machines in your account including their name, IP + and status. +
+Sort by:
+ +| + {column.render("Header")} + | + ))} ++ Edit + | +
|---|---|
|
+ {cell.column.id === "IP" && (
+ |
+ );
+ })}
+
+ |
+
+ Showing{" "} + + {pageCount === 0 + ? 0 + : pageIndex * pageSize + 1} + {" "} + to{" "} + + {pageCount === 0 + ? 0 + : pageIndex === pageCount - 1 + ? data.length + : pageIndex * pageSize + pageSize} + {" "} + of{" "} + + {data.length} + {" "} + {data.length === 1 ? "peer" : "peers"} +
+