import React, { useState } from "react"; import regeneratorRuntime from "regenerator-runtime"; import { useSelector, useDispatch } from "react-redux"; import PropTypes from "prop-types"; import { Button, Col, Row, FormControl, Card, CardGroup, Collapse, } from "react-bootstrap"; import ReactObjectTableViewer from "react-object-table-viewer"; import { Link } from "react-router-dom"; import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa"; import "./server-dashboard.css"; import { timeSince } from "../../util/timeSince"; import PaginationFooter from "../PaginationFooter/PaginationFooter"; const AccessServerButton = ({ url }) => ( ); const ServerDashboard = (props) => { let base_url = window.base_url; // sort methods var usernameDesc = (e) => e.sort((a, b) => (a.name > b.name ? 1 : -1)), usernameAsc = (e) => e.sort((a, b) => (a.name < b.name ? 1 : -1)), adminDesc = (e) => e.sort((a) => (a.admin ? -1 : 1)), adminAsc = (e) => e.sort((a) => (a.admin ? 1 : -1)), dateDesc = (e) => e.sort((a, b) => new Date(a.last_activity) - new Date(b.last_activity) > 0 ? -1 : 1 ), dateAsc = (e) => e.sort((a, b) => new Date(a.last_activity) - new Date(b.last_activity) > 0 ? 1 : -1 ), runningAsc = (e) => e.sort((a) => (a.server == null ? -1 : 1)), runningDesc = (e) => e.sort((a) => (a.server == null ? 1 : -1)); var [errorAlert, setErrorAlert] = useState(null); var [sortMethod, setSortMethod] = useState(null); var [disabledButtons, setDisabledButtons] = useState({}); const [collapseStates, setCollapseStates] = useState({}); var user_data = useSelector((state) => state.user_data), user_page = useSelector((state) => state.user_page), limit = useSelector((state) => state.limit), name_filter = useSelector((state) => state.name_filter), page = parseInt(new URLSearchParams(props.location.search).get("page")); page = isNaN(page) ? 0 : page; var slice = [page * limit, limit, name_filter]; const dispatch = useDispatch(); var { updateUsers, shutdownHub, startServer, stopServer, startAll, stopAll, history, } = props; var dispatchPageUpdate = (data, page, name_filter) => { dispatch({ type: "USER_PAGE", value: { data: data, page: page, name_filter: name_filter, }, }); }; if (!user_data) { return
; } if (page != user_page) { updateUsers(...slice).then((data) => dispatchPageUpdate(data, page, name_filter) ); } var debounce = require("lodash.debounce"); const handleSearch = debounce(async (event) => { // setNameFilter(event.target.value); updateUsers(page * limit, limit, event.target.value).then((data) => dispatchPageUpdate(data, page, name_filter) ); }, 300); if (sortMethod != null) { user_data = sortMethod(user_data); } const StopServerButton = ({ serverName, userName }) => { var [isDisabled, setIsDisabled] = useState(false); return ( ); }; const StartServerButton = ({ serverName, userName }) => { var [isDisabled, setIsDisabled] = useState(false); return ( ); }; const EditUserCell = ({ user }) => { return ( ); }; const serverRow = (user, server) => { const { servers, ...userNoServers } = user; const serverNameDash = server.name ? `-${server.name}` : ""; const userServerName = user.name + serverNameDash; const open = collapseStates[userServerName] || false; return [ {" "} {user.name} {user.admin ? "admin" : ""} {server.name ? (

{server.name}

) : (

[MAIN]

)} {server.last_activity ? timeSince(server.last_activity) : "Never"} {server.started ? ( // Stop Single-user server <> ) : ( // Start Single-user server <> )} , User Server , ]; }; let servers = user_data.flatMap((user) => { let userServers = Object.values({ "": user.server || {}, ...(user.servers || {}), }); return userServers.map((server) => [user, server]); }); return (
{errorAlert != null ? (
{errorAlert}
) : ( <> )}
{"> Manage Groups"} {servers.flatMap(([user, server]) => serverRow(user, server))}
User{" "} setSortMethod(() => method)} testid="user-sort" /> Admin{" "} setSortMethod(() => method)} testid="admin-sort" /> Server{" "} setSortMethod(() => method)} testid="server-sort" /> Last Activity{" "} setSortMethod(() => method)} testid="last-activity-sort" /> Running{" "} setSortMethod(() => method)} testid="running-status-sort" /> Actions
{/* Start all servers */} {/* Stop all servers */} {/* Shutdown Jupyterhub */}


); }; ServerDashboard.propTypes = { user_data: PropTypes.array, updateUsers: PropTypes.func, shutdownHub: PropTypes.func, startServer: PropTypes.func, stopServer: PropTypes.func, startAll: PropTypes.func, stopAll: PropTypes.func, dispatch: PropTypes.func, history: PropTypes.shape({ push: PropTypes.func, }), location: PropTypes.shape({ search: PropTypes.string, }), }; const SortHandler = (props) => { var { sorts, callback, testid } = props; var [direction, setDirection] = useState(undefined); return (
{ if (!direction) { callback(sorts.desc); setDirection("desc"); } else if (direction == "asc") { callback(sorts.desc); setDirection("desc"); } else { callback(sorts.asc); setDirection("asc"); } }} > {!direction ? ( ) : direction == "asc" ? ( ) : ( )}
); }; SortHandler.propTypes = { sorts: PropTypes.object, callback: PropTypes.func, testid: PropTypes.string, }; export default ServerDashboard;