diff --git a/jsx/build/admin-react.js.LICENSE.txt b/jsx/build/admin-react.js.LICENSE.txt index 493c5041..9e7087bc 100644 --- a/jsx/build/admin-react.js.LICENSE.txt +++ b/jsx/build/admin-react.js.LICENSE.txt @@ -37,6 +37,15 @@ object-assign * LICENSE file in the root directory of this source tree. */ +/** @license React v17.0.2 + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + /** @license React v17.0.2 * react.production.min.js * diff --git a/jsx/package.json b/jsx/package.json index 2488dbe8..4442d169 100644 --- a/jsx/package.json +++ b/jsx/package.json @@ -43,10 +43,11 @@ "lodash.debounce": "^4.0.8", "prop-types": "^15.7.2", "react": "^17.0.1", - "react-bootstrap": "^1.4.0", + "react-bootstrap": "^2.1.1", "react-dom": "^17.0.1", "react-icons": "^4.1.0", "react-multi-select-component": "^3.0.7", + "react-object-table-viewer": "^1.0.7", "react-redux": "^7.2.2", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", @@ -60,7 +61,6 @@ }, "devDependencies": { "@wojtekmaj/enzyme-adapter-react-17": "^0.6.5", - "sinon": "^13.0.1", "babel-jest": "^26.6.3", "enzyme": "^3.11.0", "eslint": "^7.18.0", @@ -68,6 +68,7 @@ "eslint-plugin-react": "^7.22.0", "identity-obj-proxy": "^3.0.0", "jest": "^26.6.3", - "prettier": "^2.2.1" + "prettier": "^2.2.1", + "sinon": "^13.0.1" } } diff --git a/jsx/src/Store.js b/jsx/src/Store.js index 0dadda20..d5194df1 100644 --- a/jsx/src/Store.js +++ b/jsx/src/Store.js @@ -14,7 +14,7 @@ export const reducers = (state = initialState, action) => { return Object.assign({}, state, { user_page: action.value.page, user_data: action.value.data, - name_filter: action.value.name_filter, + name_filter: action.value.name_filter || "", }); // Updates the client group model data and stores the page diff --git a/jsx/src/components/ServerDashboard/ServerDashboard.jsx b/jsx/src/components/ServerDashboard/ServerDashboard.jsx index 9087ee2b..9ba4720f 100644 --- a/jsx/src/components/ServerDashboard/ServerDashboard.jsx +++ b/jsx/src/components/ServerDashboard/ServerDashboard.jsx @@ -3,7 +3,17 @@ import regeneratorRuntime from "regenerator-runtime"; import { useSelector, useDispatch } from "react-redux"; import PropTypes from "prop-types"; -import { Button, Col, Row, FormControl } from "react-bootstrap"; +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"; @@ -40,6 +50,7 @@ const ServerDashboard = (props) => { 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), @@ -189,6 +200,131 @@ const ServerDashboard = (props) => { ); }; + 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 || {}, @@ -234,7 +370,7 @@ const ServerDashboard = (props) => { {"> Manage Groups"} - +
- {servers.map(([user, server], i) => { - server.name = server.name || ""; - return ( - - - - - - - - - - ); - })} + {servers.flatMap(([user, server]) => serverRow(user, server))}
@@ -373,63 +509,7 @@ const ServerDashboard = (props) => {
{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 - <> - - - - - - )} -
{ render(serverDashboardJsx(callbackSpy)); }); - let foo = screen.getByText("foo"); - let bar = screen.getByText("bar"); + let foo = screen.getByTestId("user-name-div-foo"); + let bar = screen.getByTestId("user-name-div-bar"); expect(foo).toBeVisible(); expect(bar).toBeVisible(); @@ -156,12 +156,12 @@ test("Sorts according to username", async () => { fireEvent.click(handler); let first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("bar"); + expect(first.textContent).toContain("bar"); fireEvent.click(handler); first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("foo"); + expect(first.textContent).toContain("foo"); }); test("Sorts according to admin", async () => { @@ -194,12 +194,12 @@ test("Sorts according to last activity", async () => { fireEvent.click(handler); let first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("foo"); + expect(first.textContent).toContain("foo"); fireEvent.click(handler); first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("bar"); + expect(first.textContent).toContain("bar"); }); test("Sorts according to server status (running/not running)", async () => { @@ -213,12 +213,53 @@ test("Sorts according to server status (running/not running)", async () => { fireEvent.click(handler); let first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("foo"); + expect(first.textContent).toContain("foo"); fireEvent.click(handler); first = screen.getAllByTestId("user-row-name")[0]; - expect(first.textContent).toBe("bar"); + expect(first.textContent).toContain("bar"); +}); + +test("Shows server details with button click", async () => { + let callbackSpy = mockAsync(); + + await act(async () => { + render(serverDashboardJsx(callbackSpy)); + }); + let button = screen.getByTestId("foo-collapse-button"); + let collapse = screen.getByTestId("foo-collapse"); + let collapseBar = screen.getByTestId("bar-collapse"); + + // expect().toBeVisible does not work here with collapse. + expect(collapse).toHaveClass("collapse"); + expect(collapse).not.toHaveClass("show"); + expect(collapseBar).not.toHaveClass("show"); + + await act(async () => { + fireEvent.click(button); + }); + clock.tick(400); + + expect(collapse).toHaveClass("collapse show"); + expect(collapseBar).not.toHaveClass("show"); + + await act(async () => { + fireEvent.click(button); + }); + clock.tick(400); + + expect(collapse).toHaveClass("collapse"); + expect(collapse).not.toHaveClass("show"); + expect(collapseBar).not.toHaveClass("show"); + + await act(async () => { + fireEvent.click(button); + }); + clock.tick(400); + + expect(collapse).toHaveClass("collapse show"); + expect(collapseBar).not.toHaveClass("show"); }); test("Renders nothing if required data is not available", async () => { diff --git a/jsx/src/util/withAPI.js b/jsx/src/util/withAPI.js index 69a525bb..1e6f680e 100644 --- a/jsx/src/util/withAPI.js +++ b/jsx/src/util/withAPI.js @@ -4,7 +4,7 @@ import { jhapiRequest } from "./jhapiUtil"; const withAPI = withProps(() => ({ updateUsers: (offset, limit, name_filter) => jhapiRequest( - `/users?offset=${offset}&limit=${limit}&name_filter=${name_filter}`, + `/users?offset=${offset}&limit=${limit}&name_filter=${name_filter || ""}`, "GET" ).then((data) => data.json()), updateGroups: (offset, limit) => diff --git a/jsx/yarn.lock b/jsx/yarn.lock index eb04145d..31a46af8 100644 --- a/jsx/yarn.lock +++ b/jsx/yarn.lock @@ -928,7 +928,7 @@ "@babel/plugin-transform-react-jsx-development" "^7.16.7" "@babel/plugin-transform-react-pure-annotations" "^7.16.7" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.15.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.16", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== @@ -1215,23 +1215,41 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@popperjs/core@^2.8.6": +"@popperjs/core@^2.10.1": version "2.11.4" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503" integrity sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg== -"@restart/context@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" - integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== +"@react-aria/ssr@^3.0.1": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.1.2.tgz#665a6fd56385068c7417922af2d0d71b0618e52d" + integrity sha512-amXY11ImpokvkTMeKRHjsSsG7v1yzzs6yeqArCyBIk60J3Yhgxwx9Cah+Uu/804ATFwqzN22AXIo7SdtIaMP+g== + dependencies: + "@babel/runtime" "^7.6.2" -"@restart/hooks@^0.3.26": - version "0.3.27" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.27.tgz#91f356d66d4699a8cd8b3d008402708b6a9dc505" - integrity sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw== +"@restart/hooks@^0.4.0", "@restart/hooks@^0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.5.tgz#e7acbea237bfc9e479970500cf87538b41a1ed02" + integrity sha512-tLGtY0aHeIfT7aPwUkvQuhIy3+q3w4iqmUzFLPlOAf/vNUacLaBt1j/S//jv/dQhenRh8jvswyMojCwmLvJw8A== dependencies: dequal "^2.0.2" +"@restart/ui@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.0.2.tgz#009a06ae698d624672c5e6a776efd0e8a6017842" + integrity sha512-vKGe0UBJLnbvNAjr8ljlDvphf2HkpjBjXsblmgKPvKdZBDn/mtAz89wmznaomIaEJ9VNoSEY0vA5T5MDi2jIcQ== + dependencies: + "@babel/runtime" "^7.13.16" + "@popperjs/core" "^2.10.1" + "@react-aria/ssr" "^3.0.1" + "@restart/hooks" "^0.4.0" + "@types/warning" "^3.0.0" + dequal "^2.0.2" + dom-helpers "^5.2.0" + prop-types "^15.7.2" + uncontrollable "^7.2.1" + warning "^4.0.3" + "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -1399,7 +1417,7 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" -"@types/invariant@^2.2.33": +"@types/invariant@^2.2.35": version "2.2.35" resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== @@ -1456,7 +1474,7 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== -"@types/prop-types@*", "@types/prop-types@^15.7.3": +"@types/prop-types@*", "@types/prop-types@^15.7.4": version "15.7.4" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== @@ -1478,7 +1496,7 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" -"@types/react-transition-group@^4.4.1": +"@types/react-transition-group@^4.4.4": version "4.4.4" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug== @@ -6167,30 +6185,29 @@ raw-body@2.4.3: iconv-lite "0.4.24" unpipe "1.0.0" -react-bootstrap@^1.4.0: - version "1.6.4" - resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.6.4.tgz#94d5d2422e26bba277656d3529128e14f838b7ca" - integrity sha512-z3BhBD4bEZuLP8VrYqAD7OT7axdcSkkyvWBWnS2U/4MhyabUihrUyucPWkan7aMI1XIHbmH4LCpEtzWGfx/yfA== +react-bootstrap@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.2.1.tgz#2a6ad0931e9367882ec3fc88a70ed0b8ace90b26" + integrity sha512-x8lpVQflsbevphuWbTnTNCatcbKyPJNrP2WyQ1MJYmFEcVjbTbai1yZhdlXr0QUxLQLxA8g5hQWb5TwJtaZoCA== dependencies: - "@babel/runtime" "^7.14.0" - "@restart/context" "^2.1.4" - "@restart/hooks" "^0.3.26" - "@types/invariant" "^2.2.33" - "@types/prop-types" "^15.7.3" + "@babel/runtime" "^7.17.2" + "@restart/hooks" "^0.4.5" + "@restart/ui" "^1.0.2" + "@types/invariant" "^2.2.35" + "@types/prop-types" "^15.7.4" "@types/react" ">=16.14.8" - "@types/react-transition-group" "^4.4.1" + "@types/react-transition-group" "^4.4.4" "@types/warning" "^3.0.0" classnames "^2.3.1" dom-helpers "^5.2.1" invariant "^2.2.4" - prop-types "^15.7.2" + prop-types "^15.8.1" prop-types-extra "^1.1.0" - react-overlays "^5.1.1" - react-transition-group "^4.4.1" + react-transition-group "^4.4.2" uncontrollable "^7.2.1" warning "^4.0.3" -react-dom@^17.0.1: +react-dom@17.0.2, react-dom@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== @@ -6226,19 +6243,13 @@ react-multi-select-component@^3.0.7: dependencies: goober "^2.0.30" -react-overlays@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.1.1.tgz#2e7cf49744b56537c7828ccb94cfc63dd778ae4f" - integrity sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q== +react-object-table-viewer@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/react-object-table-viewer/-/react-object-table-viewer-1.0.7.tgz#31816021fa4526641c6b66bd9433ec9b78c2e472" + integrity sha512-OezCet8+BmEdJJHO5WGPFPRWXxw4Ls6HsV4Uh1kRPlmRXLOTNqWt/ZHmH8NhTl1BA9HkdhEegKVqc2b61wDMLg== dependencies: - "@babel/runtime" "^7.13.8" - "@popperjs/core" "^2.8.6" - "@restart/hooks" "^0.3.26" - "@types/warning" "^3.0.0" - dom-helpers "^5.2.0" - prop-types "^15.7.2" - uncontrollable "^7.2.1" - warning "^4.0.3" + react "^17.0.2" + react-dom "17.0.2" react-redux@^7.2.2: version "7.2.6" @@ -6299,7 +6310,7 @@ react-test-renderer@^17.0.0: react-shallow-renderer "^16.13.1" scheduler "^0.20.2" -react-transition-group@^4.4.1: +react-transition-group@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== @@ -6309,7 +6320,7 @@ react-transition-group@^4.4.1: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^17.0.1: +react@^17.0.1, react@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== diff --git a/share/jupyterhub/static/js/admin-react.js b/share/jupyterhub/static/js/admin-react.js index 6bc10471..0cf7ccc8 100644 --- a/share/jupyterhub/static/js/admin-react.js +++ b/share/jupyterhub/static/js/admin-react.js @@ -1,2 +1,2 @@ /*! For license information please see admin-react.js.LICENSE.txt */ -(()=>{var e,t,n={966:(e,t,n)=>{"use strict";var r=n(294),a=n(935),o=r.createContext(null),l=function(e){e()},i=function(){return l},u={notify:function(){},get:function(){return[]}};function c(e,t){var n,r=u;function a(){l.onStateChange&&l.onStateChange()}function o(){n||(n=t?t.addNestedSub(a):e.subscribe(a),r=function(){var e=i(),t=null,n=null;return{clear:function(){t=null,n=null},notify:function(){e((function(){for(var e=t;e;)e.callback(),e=e.next}))},get:function(){for(var e=[],n=t;n;)e.push(n),n=n.next;return e},subscribe:function(e){var r=!0,a=n={callback:e,next:null,prev:n};return a.prev?a.prev.next=a:t=a,function(){r&&null!==t&&(r=!1,a.next?a.next.prev=a.prev:n=a.prev,a.prev?a.prev.next=a.next:t=a.next)}}}}())}var l={addNestedSub:function(e){return o(),r.subscribe(e)},notifyNestedSubs:function(){r.notify()},handleChangeWrapper:a,isSubscribed:function(){return Boolean(n)},trySubscribe:o,tryUnsubscribe:function(){n&&(n(),n=void 0,r.clear(),r=u)},getListeners:function(){return r}};return l}var s="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?r.useLayoutEffect:r.useEffect;const f=function(e){var t=e.store,n=e.context,a=e.children,l=(0,r.useMemo)((function(){var e=c(t);return e.onStateChange=e.notifyNestedSubs,{store:t,subscription:e}}),[t]),i=(0,r.useMemo)((function(){return t.getState()}),[t]);s((function(){var e=l.subscription;return e.trySubscribe(),i!==t.getState()&&e.notifyNestedSubs(),function(){e.tryUnsubscribe(),e.onStateChange=null}}),[l,i]);var u=n||o;return r.createElement(u.Provider,{value:l},a)};function d(){return d=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:"";return R("/users/"+e+"/servers/"+(t||""),"POST")},stopServer:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return R("/users/"+e+"/servers/"+(t||""),"DELETE")},startAll:function(e){return e.map((function(e){return R("/users/"+e+"/server","POST")}))},stopAll:function(e){return e.map((function(e){return R("/users/"+e+"/server","DELETE")}))},addToGroup:function(e,t){return R("/groups/"+t+"/users","POST",{users:e})},removeFromGroup:function(e,t){return R("/groups/"+t+"/users","DELETE",{users:e})},createGroup:function(e){return R("/groups/"+e,"POST")},deleteGroup:function(e){return R("/groups/"+e,"DELETE")},addUsers:function(e,t){return R("/users","POST",{usernames:e,admin:t})},editUser:function(e,t,n){return R("/users/"+e,"PATCH",{name:t,admin:n})},deleteUser:function(e){return R("/users/"+e,"DELETE")},findUser:function(e){return R("/users/"+e,"GET")},validateUser:function(e){return R("/users/"+e,"GET").then((function(e){return e.status})).then((function(e){return!(e>200)}))},failRegexEvent:function(){return null},noChangeEvent:function(){return null},refreshGroupsData:function(){return R("/groups","GET").then((function(e){return e.json()}))},refreshUserData:function(){return R("/users","GET").then((function(e){return e.json()}))}}},I=function(e){return d({},e,O())},function(e){var t=(0,r.createFactory)(e);return function(e){return t(I(e))}});var I;function M(e){return"/"===e.charAt(0)}function z(e,t){for(var n=t,r=n+1,a=e.length;r=0;s--){var f=a[s];"."===f?z(a,s):".."===f?(z(a,s),c++):c&&(z(a,s),c--)}if(!i)for(;c--;c)a.unshift("..");!i||""===a[0]||a[0]&&M(a[0])||a.unshift("");var d=a.join("/");return n&&"/"!==d.substr(-1)&&(d+="/"),d};"undefined"==typeof window||!window.document||window.document.createElement;var D=n(697),U=n.n(D),$=1073741823,B="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};function H(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,r){e=n,t.forEach((function(t){return t(e,r)}))}}}const V=r.createContext||function(e,t){var n,a,o,l="__create-react-context-"+((B[o="__global_unique_id__"]=(B[o]||0)+1)+"__"),i=function(e){function n(){var t;return(t=e.apply(this,arguments)||this).emitter=H(t.props.value),t}P(n,e);var r=n.prototype;return r.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},r.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(l=a)?0!==o||1/o==1/l:o!=o&&l!=l)?n=0:(n="function"==typeof t?t(r,a):$,0!=(n|=0)&&this.emitter.set(e.value,n))}var o,l},r.render=function(){return this.props.children},n}(r.Component);i.childContextTypes=((n={})[l]=U().object.isRequired,n);var u=function(t){function n(){var e;return(e=t.apply(this,arguments)||this).state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}P(n,t);var r=n.prototype;return r.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?$:t},r.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?$:e},r.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},r.getValue=function(){return this.context[l]?this.context[l].get():e},r.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(r.Component);return u.contextTypes=((a={})[l]=U().object,a),{Provider:i,Consumer:u}};function W(e,t){if(!e)throw new Error("Invariant failed")}var G=n(779),Q=n.n(G);function q(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r=0||(a[n]=e[n]);return a}n(663);var K=function(e){var t=V();return t.displayName=e,t},Y=K("Router-History"),X=K("Router"),J=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._isMounted?n.setState({location:e}):n._pendingLocation=e}))),n}P(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){this._isMounted=!0,this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return r.createElement(X.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},r.createElement(Y.Provider,{children:this.props.children||null,value:this.props.history}))},t}(r.Component);r.Component,r.Component;var Z={},ee=0;function te(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,l=n.strict,i=void 0!==l&&l,u=n.sensitive,c=void 0!==u&&u;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=Z[n]||(Z[n]={});if(r[e])return r[e];var a=[],o={regexp:Q()(e,a,t),keys:a};return ee<1e4&&(r[e]=o,ee++),o}(n,{end:o,strict:i,sensitive:c}),a=r.regexp,l=r.keys,u=a.exec(e);if(!u)return null;var s=u[0],f=u.slice(1),d=e===s;return o&&!d?null:{path:n,url:"/"===n&&""===s?"/":s,isExact:d,params:l.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var ne=function(e){function t(){return e.apply(this,arguments)||this}return P(t,e),t.prototype.render=function(){var e=this;return r.createElement(X.Consumer,null,(function(t){t||W(!1);var n=e.props.location||t.location,a=d({},t,{location:n,match:e.props.computedMatch?e.props.computedMatch:e.props.path?te(n.pathname,e.props):t.match}),o=e.props,l=o.children,i=o.component,u=o.render;return Array.isArray(l)&&function(e){return 0===r.Children.count(e)}(l)&&(l=null),r.createElement(X.Provider,{value:a},a.match?l?"function"==typeof l?l(a):l:i?r.createElement(i,a):u?u(a):null:"function"==typeof l?l(a):null)}))},t}(r.Component);r.Component;var re=function(e){function t(){return e.apply(this,arguments)||this}return P(t,e),t.prototype.render=function(){var e=this;return r.createElement(X.Consumer,null,(function(t){t||W(!1);var n,a,o=e.props.location||t.location;return r.Children.forEach(e.props.children,(function(e){if(null==a&&r.isValidElement(e)){n=e;var l=e.props.path||e.props.from;a=l?te(o.pathname,d({},e.props,{path:l})):t.match}})),a?r.cloneElement(n,{location:o,computedMatch:a}):null}))},t}(r.Component);function ae(e){return"/"===e.charAt(0)?e:"/"+e}function oe(e){return"/"===e.charAt(0)?e.substr(1):e}function le(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function ie(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function ue(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function ce(e,t,n,r){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=d({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(e){throw e instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):e}return n&&(a.key=n),r?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=F(a.pathname,r.pathname)):a.pathname=r.pathname:a.pathname||(a.pathname="/"),a}function se(){var e=null,t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r=1?r.createElement("button",{className:"btn btn-sm btn-light spaced"},r.createElement(_e,{to:"".concat(t,"?page=").concat(n-1)},r.createElement("span",{className:"active-pagination"},"Previous"))):r.createElement("button",{className:"btn btn-sm btn-light spaced"},r.createElement("span",{className:"inactive-pagination"},"Previous")),l>=a?r.createElement("button",{className:"btn btn-sm btn-light spaced"},r.createElement(_e,{to:"".concat(t,"?page=").concat(n+1)},r.createElement("span",{className:"active-pagination"},"Next"))):r.createElement("button",{className:"btn btn-sm btn-light spaced"},r.createElement("span",{className:"inactive-pagination"},"Next"))))};pt.propTypes={endpoint:U().string,page:U().number,limit:U().number,numOffset:U().number,numElements:U().number};const mt=pt;function ht(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function vt(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function yt(e,t,n,r,a,o,l){try{var i=e[o](l),u=i.value}catch(e){return void n(e)}i.done?t(u):Promise.resolve(u).then(r,a)}function gt(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o=[],l=!0,i=!1;try{for(n=n.call(e);!(l=(r=n.next()).done)&&(o.push(r.value),!t||o.length!==t);l=!0);}catch(e){i=!0,a=e}finally{try{l||null==n.return||n.return()}finally{if(i)throw a}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return bt(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?bt(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function bt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nt.name?1:-1}))},o=function(e){return e.sort((function(e,t){return e.name Manage Groups"))),r.createElement("table",{className:"table table-striped table-bordered table-hover"},r.createElement("thead",{className:"admin-table-head"},r.createElement("tr",null,r.createElement("th",{id:"user-header"},"User"," ",r.createElement(kt,{sorts:{asc:o,desc:a},callback:function(e){return f((function(){return e}))},testid:"user-sort"})),r.createElement("th",{id:"admin-header"},"Admin"," ",r.createElement(kt,{sorts:{asc:function(e){return e.sort((function(e){return e.admin?1:-1}))},desc:function(e){return e.sort((function(e){return e.admin?-1:1}))}},callback:function(e){return f((function(){return e}))},testid:"admin-sort"})),r.createElement("th",{id:"server-header"},"Server"," ",r.createElement(kt,{sorts:{asc:o,desc:a},callback:function(e){return f((function(){return e}))},testid:"server-sort"})),r.createElement("th",{id:"last-activity-header"},"Last Activity"," ",r.createElement(kt,{sorts:{asc:function(e){return e.sort((function(e,t){return new Date(e.last_activity)-new Date(t.last_activity)>0?1:-1}))},desc:function(e){return e.sort((function(e,t){return new Date(e.last_activity)-new Date(t.last_activity)>0?-1:1}))}},callback:function(e){return f((function(){return e}))},testid:"last-activity-sort"})),r.createElement("th",{id:"running-status-header"},"Running"," ",r.createElement(kt,{sorts:{asc:function(e){return e.sort((function(e){return null==e.server?-1:1}))},desc:function(e){return e.sort((function(e){return null==e.server?1:-1}))}},callback:function(e){return f((function(){return e}))},testid:"running-status-sort"})),r.createElement("th",{id:"actions-header"},"Actions"))),r.createElement("tbody",null,r.createElement("tr",{className:"noborder"},r.createElement("td",null,r.createElement(rt,{variant:"light",className:"add-users-button"},r.createElement(_e,{to:"/add-users"},"Add Users"))),r.createElement("td",null),r.createElement("td",null),r.createElement("td",null,r.createElement(rt,{variant:"primary",className:"start-all","data-testid":"start-all",onClick:function(){Promise.all(C(p.map((function(e){return e.name})))).then((function(e){var t=e.filter((function(e){return!e.ok}));return t.length>0&&u("Failed to start ".concat(t.length," ").concat(t.length>1?"servers":"server",". ").concat(t.length>1?"Are they ":"Is it "," already running?")),e})).then((function(e){return k.apply(void 0,b).then((function(e){O(e,g,v)})).catch((function(){return u("Failed to update users list.")})),e})).catch((function(){return u("Failed to start servers.")}))}},"Start All"),r.createElement("span",null," "),r.createElement(rt,{variant:"danger",className:"stop-all","data-testid":"stop-all",onClick:function(){Promise.all(N(p.map((function(e){return e.name})))).then((function(e){var t=e.filter((function(e){return!e.ok}));return t.length>0&&u("Failed to stop ".concat(t.length," ").concat(t.length>1?"servers":"server",". ").concat(t.length>1?"Are they ":"Is it "," already stopped?")),e})).then((function(e){return k.apply(void 0,b).then((function(e){O(e,g,v)})).catch((function(){return u("Failed to update users list.")})),e})).catch((function(){return u("Failed to stop servers.")}))}},"Stop All")),r.createElement("td",null,r.createElement(rt,{variant:"danger",id:"shutdown-button",onClick:S},"Shutdown Hub"))),A.map((function(e,n){var a,o,l,i,u,c,s=gt(e,2),f=s[0],d=s[1];return d.name=d.name||"",r.createElement("tr",{key:n+"row",className:"user-row"},r.createElement("td",{"data-testid":"user-row-name"},f.name),r.createElement("td",{"data-testid":"user-row-admin"},f.admin?"admin":""),r.createElement("td",{"data-testid":"user-row-server"},d.name?r.createElement("p",{class:"text-secondary"},d.name):r.createElement("p",{style:{color:"lightgrey"}},"[MAIN]")),r.createElement("td",{"data-testid":"user-row-last-activity"},d.last_activity?(a=d.last_activity,6e4,o=36e5,l=864e5,i=2592e6,u=31536e6,(c=Date.now()-Date.parse(a))<6e4?Math.round(c/1e3)+" seconds ago":c0?n.map((function(e,n){return r.createElement("li",{className:"list-group-item",key:"group-item"+n},r.createElement("span",{className:"badge badge-pill badge-success"},e.users.length+" users"),r.createElement(_e,{to:{pathname:"/group-edit",state:{group_data:e,user_data:t}}},e.name))})):r.createElement("div",null,r.createElement("h4",null,"no groups created..."))),r.createElement(mt,{endpoint:"/groups",page:i,limit:o,numOffset:u[0],numElements:n.length})),r.createElement("div",{className:"panel-footer"},r.createElement("button",{className:"btn btn-light adjacent-span-spacing"},r.createElement(_e,{to:"/"},"Back")),r.createElement("button",{className:"btn btn-primary adjacent-span-spacing",onClick:function(){s.push("/create-group")}},"New Group"))))))):r.createElement("div",{"data-testid":"no-show"})};xt.propTypes={user_data:U().array,groups_data:U().array,updateUsers:U().func,updateGroups:U().func,history:U().shape({push:U().func}),location:U().shape({search:U().string})};const _t=xt;function Ct(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o=[],l=!0,i=!1;try{for(n=n.call(e);!(l=(r=n.next()).done)&&(o.push(r.value),!t||o.length!==t);l=!0);}catch(e){i=!0,a=e}finally{try{l||null==n.return||n.return()}finally{if(i)throw a}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return Nt(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Nt(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Nt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&r.push(m(e,S.name)),t.length>0&&r.push(h(t,S.name)),Promise.all(r).then((function(e){0==e.map((function(e){return e.status})).filter((function(e){return e>=300})).length?g(0,f).then((function(e){return p(e,0)})).then((function(){return w.push("/groups")})):s("Failed to edit group.")})).catch((function(){console.log("outer"),s("Failed to edit group.")}))}else w.push("/groups")}},"Apply"),r.createElement("button",{id:"delete-group","data-testid":"delete-group",className:"btn btn-danger",style:{float:"right"},onClick:function(){var e=S.name;v(e).then((function(e){e.status<300?g(0,f).then((function(e){return p(e,0)})).then((function(){return w.push("/groups")})):s("Failed to delete group.")})).catch((function(){return s("Failed to delete group.")}))}},"Delete Group"),r.createElement("br",null),r.createElement("br",null)))):r.createElement("div",null)};jt.propTypes={location:U().shape({state:U().shape({group_data:U().object,callback:U().func})}),history:U().shape({push:U().func}),addToGroup:U().func,removeFromGroup:U().func,deleteGroup:U().func,updateGroups:U().func,validateUser:U().func};const Rt=jt;function At(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o=[],l=!0,i=!1;try{for(n=n.call(e);!(l=(r=n.next()).done)&&(o.push(r.value),!t||o.length!==t);l=!0);}catch(e){i=!0,a=e}finally{try{l||null==n.return||n.return()}finally{if(i)throw a}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return It(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?It(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function It(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n2&&0==/[!@#$%^&*(),.?":{}|<>]/g.test(e)}));e.lengthe.length)&&(t=e.length);for(var n=0,r=new Array(t);n2&&0==/[!@#$%^&*(),.?":{}|<>]/g.test(g)?u(m,""!=g?g:m,k).then((function(e){e.status<300?f(0,t).then((function(e){return i(e,0)})).then((function(){return d.push("/")})).catch((function(){return o("Could not update users list.")})):o("Failed to edit user.")})).catch((function(){o("Failed to edit user.")})):o("Failed to edit user. Make sure the username does not contain special characters."):u(m,m,k).then((function(e){e.status<300?f(0,t).then((function(e){return i(e,0)})).then((function(){return d.push("/")})).catch((function(){return o("Could not update users list.")})):o("Failed to edit user.")})).catch((function(){o("Failed to edit user.")})):s()}},"Apply")))))))};Vt.propTypes={location:U().shape({state:U().shape({username:U().string,has_admin:U().bool})}),history:U().shape({push:U().func}),editUser:U().func,deleteUser:U().func,failRegexEvent:U().func,noChangeEvent:U().func,updateUsers:U().func};const Wt=Vt;n(137);var Gt=function e(t,n,r){var a;if("function"==typeof n&&"function"==typeof r||"function"==typeof r&&"function"==typeof arguments[3])throw new Error(k(0));if("function"==typeof n&&void 0===r&&(r=n,n=void 0),void 0!==r){if("function"!=typeof r)throw new Error(k(1));return r(e)(t,n)}if("function"!=typeof t)throw new Error(k(2));var o=t,l=n,i=[],u=i,c=!1;function s(){u===i&&(u=i.slice())}function f(){if(c)throw new Error(k(3));return l}function d(e){if("function"!=typeof e)throw new Error(k(4));if(c)throw new Error(k(5));var t=!0;return s(),u.push(e),function(){if(t){if(c)throw new Error(k(6));t=!1,s();var n=u.indexOf(e);u.splice(n,1),i=null}}}function p(e){if(!C(e))throw new Error(k(7));if(void 0===e.type)throw new Error(k(8));if(c)throw new Error(k(9));try{c=!0,l=o(l,e)}finally{c=!1}for(var t=i=u,n=0;n0&&void 0!==arguments[0]?arguments[0]:j,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case"USER_PAGE":return Object.assign({},e,{user_page:t.value.page,user_data:t.value.data,name_filter:t.value.name_filter});case"GROUPS_PAGE":return Object.assign({},e,{groups_page:t.value.page,groups_data:t.value.data});default:return e}}),j),Qt=function(){return(0,r.useEffect)((function(){var e=j.limit,t=j.groups_page;R("/users?offset=".concat(j.user_page*e,"&limit=").concat(e),"GET").then((function(e){return e.json()})).then((function(e){return Gt.dispatch({type:"USER_PAGE",value:{data:e,page:0}})})).catch((function(e){return console.log(e)})),R("/groups?offset=".concat(t*e,"&limit=").concat(e),"GET").then((function(e){return e.json()})).then((function(e){return Gt.dispatch({type:"GROUPS_PAGE",value:{data:e,page:0}})})).catch((function(e){return console.log(e)}))})),r.createElement("div",{className:"resets"},r.createElement(f,{store:Gt},r.createElement(be,null,r.createElement(re,null,r.createElement(ne,{exact:!0,path:"/",component:T(A)(St)}),r.createElement(ne,{exact:!0,path:"/groups",component:T(A)(_t)}),r.createElement(ne,{exact:!0,path:"/group-edit",component:T(A)(Rt)}),r.createElement(ne,{exact:!0,path:"/create-group",component:T(A)(zt)}),r.createElement(ne,{exact:!0,path:"/add-users",component:T(A)($t)}),r.createElement(ne,{exact:!0,path:"/edit-user",component:T(A)(Wt)})))))};a.render(r.createElement(Qt,null),document.getElementById("react-admin-hook"))},790:(e,t)=>{"use strict";t.E=function(){var e=[],t=e;function n(){t===e&&(t=e.slice())}return{listen:function(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var r=!0;return n(),t.push(e),function(){if(r){r=!1,n();var a=t.indexOf(e);t.splice(a,1)}}},emit:function(){for(var n=e=t,r=0;r{var n;!function(){"use strict";var r={}.hasOwnProperty;function a(){for(var e=[],t=0;t{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(645),a=n.n(r),o=n(223),l=a()((function(e){return e[1]}));l.i(o.default),l.push([e.id,".users-container {\n width: 100%;\n position: relative;\n padding: 5px;\n overflow-x: scroll;\n}\n\n.users-container div {\n display: inline-block;\n}\n\n.users-container .item {\n padding: 3px;\n padding-left: 6px;\n padding-right: 6px;\n border-radius: 3px;\n font-size: 14px;\n margin-left: 4px;\n margin-right: 4px;\n transition: 30ms ease-in all;\n cursor: pointer;\n user-select: none;\n border: solid 1px #dfdfdf;\n}\n\n.users-container .item.unselected {\n background-color: #f7f7f7;\n color: #777;\n}\n\n.users-container .item.selected {\n background-color: orange;\n color: white;\n}\n\n.users-container .item:hover {\n opacity: 0.7;\n}\n",""]);const i=l},457:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(645),a=n.n(r),o=n(223),l=a()((function(e){return e[1]}));l.i(o.default),l.push([e.id,".pagination-footer * button {\n margin-right: 10px;\n}\n\n.pagination-footer * .inactive-pagination {\n color: gray;\n cursor: not-allowed;\n}\n\n.pagination-footer * button.spaced {\n color: var(--blue);\n}\n",""]);const i=l},642:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(645),a=n.n(r),o=n(223),l=a()((function(e){return e[1]}));l.i(o.default),l.push([e.id,".server-dashboard-container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.server-dashboard-container .add-users-button {\n border: 1px solid #ddd;\n}\n\n.server-dashboard-container tbody {\n color: #626262;\n}\n\n.admin-table-head {\n user-select: none;\n}\n\n.sort-icon {\n display: inline-block;\n top: 0.125em;\n position: relative;\n user-select: none;\n cursor: pointer;\n}\n\ntr.noborder > td {\n border: none !important;\n}\n",""]);const i=l},223:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(645),a=n.n(r)()((function(e){return e[1]}));a.push([e.id,":root {\n --red: #d7191e;\n --orange: #f1ad4e;\n --blue: #2e7ab6;\n --white: #ffffff;\n --gray: #f7f7f7;\n}\n\n/* Color Classes */\n.red {\n background-color: var(--red);\n}\n.orange {\n background-color: var(--orange);\n}\n.blue {\n background-color: var(--blue);\n}\n.white {\n background-color: var(--white);\n}\n\n/* Resets */\n\n.resets .modal {\n display: block;\n visibility: visible;\n z-index: 2000;\n}\n\n/* Global Util Classes */\n.adjacent-span-spacing {\n margin-right: 5px;\n margin-left: 5px;\n}\n",""]);const o=a},645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=e(t);return t[2]?"@media ".concat(t[2]," {").concat(n,"}"):n})).join("")},t.i=function(e,n,r){"string"==typeof e&&(e=[[null,e,""]]);var a={};if(r)for(var o=0;o{"use strict";var t=Object.prototype.hasOwnProperty;function n(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}e.exports=function(e,r){if(n(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var a=Object.keys(e),o=Object.keys(r);if(a.length!==o.length)return!1;for(var l=0;l{"use strict";var r=n(296),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},l={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function u(e){return r.isMemo(e)?l:i[e.$$typeof]||a}i[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[r.Memo]=l;var c=Object.defineProperty,s=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var l=s(n);f&&(l=l.concat(f(n)));for(var i=u(t),h=u(n),v=0;v{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,l=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,u=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,s=n?Symbol.for("react.async_mode"):60111,f=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,v=n?Symbol.for("react.lazy"):60116,y=n?Symbol.for("react.block"):60121,g=n?Symbol.for("react.fundamental"):60117,b=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function E(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case s:case f:case o:case i:case l:case p:return e;default:switch(e=e&&e.$$typeof){case c:case d:case v:case h:case u:return e;default:return t}}case a:return t}}}function k(e){return E(e)===f}t.AsyncMode=s,t.ConcurrentMode=f,t.ContextConsumer=c,t.ContextProvider=u,t.Element=r,t.ForwardRef=d,t.Fragment=o,t.Lazy=v,t.Memo=h,t.Portal=a,t.Profiler=i,t.StrictMode=l,t.Suspense=p,t.isAsyncMode=function(e){return k(e)||E(e)===s},t.isConcurrentMode=k,t.isContextConsumer=function(e){return E(e)===c},t.isContextProvider=function(e){return E(e)===u},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return E(e)===d},t.isFragment=function(e){return E(e)===o},t.isLazy=function(e){return E(e)===v},t.isMemo=function(e){return E(e)===h},t.isPortal=function(e){return E(e)===a},t.isProfiler=function(e){return E(e)===i},t.isStrictMode=function(e){return E(e)===l},t.isSuspense=function(e){return E(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===f||e===i||e===l||e===p||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===h||e.$$typeof===u||e.$$typeof===c||e.$$typeof===d||e.$$typeof===g||e.$$typeof===b||e.$$typeof===w||e.$$typeof===y)},t.typeOf=E},296:(e,t,n)=>{"use strict";e.exports=n(103)},954:(e,t,n)=>{var r=/^\s+|\s+$/g,a=/^[-+]0x[0-9a-f]+$/i,o=/^0b[01]+$/i,l=/^0o[0-7]+$/i,i=parseInt,u="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,c="object"==typeof self&&self&&self.Object===Object&&self,s=u||c||Function("return this")(),f=Object.prototype.toString,d=Math.max,p=Math.min,m=function(){return s.Date.now()};function h(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function v(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==f.call(e)}(e))return NaN;if(h(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=h(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(r,"");var n=o.test(e);return n||l.test(e)?i(e.slice(2),n?2:8):a.test(e)?NaN:+e}e.exports=function(e,t,n){var r,a,o,l,i,u,c=0,s=!1,f=!1,y=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function g(t){var n=r,o=a;return r=a=void 0,c=t,l=e.apply(o,n)}function b(e){return c=e,i=setTimeout(E,t),s?g(e):l}function w(e){var n=e-u;return void 0===u||n>=t||n<0||f&&e-c>=o}function E(){var e=m();if(w(e))return k(e);i=setTimeout(E,function(e){var n=t-(e-u);return f?p(n,o-(e-c)):n}(e))}function k(e){return i=void 0,y&&r?g(e):(r=a=void 0,l)}function S(){var e=m(),n=w(e);if(r=arguments,a=this,u=e,n){if(void 0===i)return b(u);if(f)return i=setTimeout(E,t),g(u)}return void 0===i&&(i=setTimeout(E,t)),l}return t=v(t)||0,h(n)&&(s=!!n.leading,o=(f="maxWait"in n)?d(v(n.maxWait)||0,t):o,y="trailing"in n?!!n.trailing:y),S.cancel=function(){void 0!==i&&clearTimeout(i),c=0,r=u=a=i=void 0},S.flush=function(){return void 0===i?l:k(m())},S}},418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var l,i,u=a(e),c=1;c{var r=n(173);e.exports=function e(t,n,a){return r(n)||(a=n||a,n=[]),a=a||{},t instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},391:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){for(var e=arguments.length,t=Array(e),n=0;n{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){function t(t,n,r,a,o,l){var i=a||"<>",u=l||r;if(null==n[r])return t?new Error("Required "+o+" `"+u+"` was not specified in `"+i+"`."):null;for(var c=arguments.length,s=Array(c>6?c-6:0),f=6;f{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,l){if(l!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},697:(e,t,n)=>{e.exports=n(703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},448:(e,t,n)=>{"use strict";var r=n(294),a=n(418),o=n(840);function l(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n