diff --git a/jsx/src/App.jsx b/jsx/src/App.jsx index 7047e50a..b99a59d7 100644 --- a/jsx/src/App.jsx +++ b/jsx/src/App.jsx @@ -21,12 +21,13 @@ const store = createStore(reducers, initialState); const App = (props) => { useEffect(() => { - jhapiRequest("/users", "GET") + let { limit, user_page, groups_page } = initialState; + jhapiRequest(`/users?offset=${user_page * limit}&limit=${limit}`, "GET") .then((data) => data.json()) .then((data) => store.dispatch({ type: "USER_DATA", value: data })) .catch((err) => console.log(err)); - jhapiRequest("/groups", "GET") + jhapiRequest(`/groups?offset=${groups_page * limit}&limit=${limit}`, "GET") .then((data) => data.json()) .then((data) => store.dispatch({ type: "GROUPS_DATA", value: data })) .catch((err) => console.log(err)); diff --git a/jsx/src/Store.js b/jsx/src/Store.js index 929b1e37..fa1824ac 100644 --- a/jsx/src/Store.js +++ b/jsx/src/Store.js @@ -2,7 +2,10 @@ import { combineReducers } from "redux"; export const initialState = { user_data: undefined, + user_page: 0, groups_data: undefined, + groups_page: 0, + limit: 50, manage_groups_modal: false, }; @@ -10,6 +13,11 @@ export const reducers = (state = initialState, action) => { switch (action.type) { case "USER_DATA": return Object.assign({}, state, { user_data: action.value }); + case "USER_PAGE": + return Object.assign({}, state, { + user_page: action.value.page, + user_data: action.value.data, + }); case "GROUPS_DATA": return Object.assign({}, state, { groups_data: action.value }); case "TOGGLE_MANAGE_GROUPS_MODAL": diff --git a/jsx/src/components/ServerDashboard/ServerDashboard.jsx b/jsx/src/components/ServerDashboard/ServerDashboard.jsx index d110f939..f8dd3fd6 100644 --- a/jsx/src/components/ServerDashboard/ServerDashboard.jsx +++ b/jsx/src/components/ServerDashboard/ServerDashboard.jsx @@ -31,6 +31,11 @@ const ServerDashboard = (props) => { var [sortMethod, setSortMethod] = useState(null); var user_data = useSelector((state) => state.user_data); + var user_page = useSelector((state) => state.user_page); + var limit = useSelector((state) => state.limit); + var page = parseInt(new URLSearchParams(props.location.search).get("page")); + page = isNaN(page) ? 0 : page; + var slice = [page * limit, limit]; const dispatch = useDispatch(); @@ -51,10 +56,26 @@ const ServerDashboard = (props) => { }); }; + var dispatchPageChange = (data, page) => { + dispatch({ + type: "USER_PAGE", + value: { + data: data, + page: page, + }, + }); + }; + if (!user_data) { return
; } + if (page != user_page) { + updateUsers(...slice) + .then((data) => data.json()) + .then((data) => dispatchPageChange(data, page)); + } + if (sortMethod != null) { user_data = sortMethod(user_data); } @@ -116,7 +137,7 @@ const ServerDashboard = (props) => { onClick={() => { Promise.all(startAll(user_data.map((e) => e.name))) .then((res) => { - updateUsers() + updateUsers(...slice) .then((data) => data.json()) .then((data) => { dispatchUserUpdate(data); @@ -137,7 +158,7 @@ const ServerDashboard = (props) => { onClick={() => { Promise.all(stopAll(user_data.map((e) => e.name))) .then((res) => { - updateUsers() + updateUsers(...slice) .then((data) => data.json()) .then((data) => { dispatchUserUpdate(data); @@ -177,7 +198,7 @@ const ServerDashboard = (props) => { onClick={() => stopServer(e.name) .then((res) => { - updateUsers() + updateUsers(...slice) .then((data) => data.json()) .then((data) => { dispatchUserUpdate(data); @@ -196,7 +217,7 @@ const ServerDashboard = (props) => { onClick={() => startServer(e.name) .then((res) => { - updateUsers() + updateUsers(...slice) .then((data) => data.json()) .then((data) => { dispatchUserUpdate(data); @@ -232,6 +253,25 @@ const ServerDashboard = (props) => { ))} +

+

+ Displaying users {slice[0]}-{slice[0] + user_data.length} + {user_data.length >= limit ? ( + + ) : ( + <> + )} + {page >= 1 ? ( + + ) : ( + <> + )} +

+

); @@ -249,6 +289,9 @@ ServerDashboard.propTypes = { history: PropTypes.shape({ push: PropTypes.func, }), + location: PropTypes.shape({ + search: PropTypes.string, + }), }; const SortHandler = (props) => { diff --git a/jsx/src/util/withAPI.js b/jsx/src/util/withAPI.js index 1e84d764..4896db10 100644 --- a/jsx/src/util/withAPI.js +++ b/jsx/src/util/withAPI.js @@ -2,7 +2,8 @@ import { withProps } from "recompose"; import { jhapiRequest } from "./jhapiUtil"; const withAPI = withProps((props) => ({ - updateUsers: (cb) => jhapiRequest("/users", "GET"), + updateUsers: (offset, limit) => + jhapiRequest(`/users?offset=${offset}&limit=${limit}`, "GET"), shutdownHub: () => jhapiRequest("/shutdown", "POST"), startServer: (name) => jhapiRequest("/users/" + name + "/server", "POST"), stopServer: (name) => jhapiRequest("/users/" + name + "/server", "DELETE"), diff --git a/share/jupyterhub/static/js/admin-react.js b/share/jupyterhub/static/js/admin-react.js index 7d6af9a5..7104c677 100644 --- a/share/jupyterhub/static/js/admin-react.js +++ b/share/jupyterhub/static/js/admin-react.js @@ -64,7 +64,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! redux */ \"./node_modules/redux/es/redux.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var _Store__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Store */ \"./src/Store.js\");\n/* harmony import */ var _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\n/* harmony import */ var _util_withAPI__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./util/withAPI */ \"./src/util/withAPI.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router/esm/react-router.js\");\n/* harmony import */ var _components_ServerDashboard_ServerDashboard__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/ServerDashboard/ServerDashboard */ \"./src/components/ServerDashboard/ServerDashboard.jsx\");\n/* harmony import */ var _components_Groups_Groups__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/Groups/Groups */ \"./src/components/Groups/Groups.jsx\");\n/* harmony import */ var _components_GroupEdit_GroupEdit__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/GroupEdit/GroupEdit */ \"./src/components/GroupEdit/GroupEdit.jsx\");\n/* harmony import */ var _components_CreateGroup_CreateGroup__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/CreateGroup/CreateGroup */ \"./src/components/CreateGroup/CreateGroup.jsx\");\n/* harmony import */ var _components_AddUser_AddUser__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/AddUser/AddUser */ \"./src/components/AddUser/AddUser.jsx\");\n/* harmony import */ var _components_EditUser_EditUser__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/EditUser/EditUser */ \"./src/components/EditUser/EditUser.jsx\");\n/* harmony import */ var _style_root_css__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./style/root.css */ \"./src/style/root.css\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar store = (0,redux__WEBPACK_IMPORTED_MODULE_14__.createStore)(_Store__WEBPACK_IMPORTED_MODULE_4__.reducers, _Store__WEBPACK_IMPORTED_MODULE_4__.initialState);\n\nvar App = function App(props) {\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {\n (0,_util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__.jhapiRequest)(\"/users\", \"GET\").then(function (data) {\n return data.json();\n }).then(function (data) {\n return store.dispatch({\n type: \"USER_DATA\",\n value: data\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n (0,_util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__.jhapiRequest)(\"/groups\", \"GET\").then(function (data) {\n return data.json();\n }).then(function (data) {\n return store.dispatch({\n type: \"GROUPS_DATA\",\n value: data\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n });\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"resets\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_redux__WEBPACK_IMPORTED_MODULE_2__.Provider, {\n store: store\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_15__.HashRouter, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Switch, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_ServerDashboard_ServerDashboard__WEBPACK_IMPORTED_MODULE_7__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/groups\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_Groups_Groups__WEBPACK_IMPORTED_MODULE_8__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/group-edit\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_GroupEdit_GroupEdit__WEBPACK_IMPORTED_MODULE_9__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/create-group\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_CreateGroup_CreateGroup__WEBPACK_IMPORTED_MODULE_10__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/add-users\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_AddUser_AddUser__WEBPACK_IMPORTED_MODULE_11__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/edit-user\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_EditUser_EditUser__WEBPACK_IMPORTED_MODULE_12__.default)\n })))));\n};\n\nreact_dom__WEBPACK_IMPORTED_MODULE_1__.render( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(App, null), document.getElementById(\"react-admin-hook\"));\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/App.jsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! redux */ \"./node_modules/redux/es/redux.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var _Store__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Store */ \"./src/Store.js\");\n/* harmony import */ var _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\n/* harmony import */ var _util_withAPI__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./util/withAPI */ \"./src/util/withAPI.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router/esm/react-router.js\");\n/* harmony import */ var _components_ServerDashboard_ServerDashboard__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/ServerDashboard/ServerDashboard */ \"./src/components/ServerDashboard/ServerDashboard.jsx\");\n/* harmony import */ var _components_Groups_Groups__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/Groups/Groups */ \"./src/components/Groups/Groups.jsx\");\n/* harmony import */ var _components_GroupEdit_GroupEdit__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/GroupEdit/GroupEdit */ \"./src/components/GroupEdit/GroupEdit.jsx\");\n/* harmony import */ var _components_CreateGroup_CreateGroup__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/CreateGroup/CreateGroup */ \"./src/components/CreateGroup/CreateGroup.jsx\");\n/* harmony import */ var _components_AddUser_AddUser__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/AddUser/AddUser */ \"./src/components/AddUser/AddUser.jsx\");\n/* harmony import */ var _components_EditUser_EditUser__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/EditUser/EditUser */ \"./src/components/EditUser/EditUser.jsx\");\n/* harmony import */ var _style_root_css__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./style/root.css */ \"./src/style/root.css\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar store = (0,redux__WEBPACK_IMPORTED_MODULE_14__.createStore)(_Store__WEBPACK_IMPORTED_MODULE_4__.reducers, _Store__WEBPACK_IMPORTED_MODULE_4__.initialState);\n\nvar App = function App(props) {\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {\n var limit = _Store__WEBPACK_IMPORTED_MODULE_4__.initialState.limit,\n user_page = _Store__WEBPACK_IMPORTED_MODULE_4__.initialState.user_page,\n groups_page = _Store__WEBPACK_IMPORTED_MODULE_4__.initialState.groups_page;\n (0,_util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__.jhapiRequest)(\"/users?offset=\".concat(user_page * limit, \"&limit=\").concat(limit), \"GET\").then(function (data) {\n return data.json();\n }).then(function (data) {\n return store.dispatch({\n type: \"USER_DATA\",\n value: data\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n (0,_util_jhapiUtil__WEBPACK_IMPORTED_MODULE_5__.jhapiRequest)(\"/groups?offset=\".concat(groups_page * limit, \"&limit=\").concat(limit), \"GET\").then(function (data) {\n return data.json();\n }).then(function (data) {\n return store.dispatch({\n type: \"GROUPS_DATA\",\n value: data\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n });\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"resets\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_redux__WEBPACK_IMPORTED_MODULE_2__.Provider, {\n store: store\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_15__.HashRouter, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Switch, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_ServerDashboard_ServerDashboard__WEBPACK_IMPORTED_MODULE_7__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/groups\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_Groups_Groups__WEBPACK_IMPORTED_MODULE_8__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/group-edit\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_GroupEdit_GroupEdit__WEBPACK_IMPORTED_MODULE_9__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/create-group\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_CreateGroup_CreateGroup__WEBPACK_IMPORTED_MODULE_10__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/add-users\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_AddUser_AddUser__WEBPACK_IMPORTED_MODULE_11__.default)\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_16__.Route, {\n exact: true,\n path: \"/edit-user\",\n component: (0,recompose__WEBPACK_IMPORTED_MODULE_3__.compose)(_util_withAPI__WEBPACK_IMPORTED_MODULE_6__.default)(_components_EditUser_EditUser__WEBPACK_IMPORTED_MODULE_12__.default)\n })))));\n};\n\nreact_dom__WEBPACK_IMPORTED_MODULE_1__.render( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(App, null), document.getElementById(\"react-admin-hook\"));\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/App.jsx?"); /***/ }), @@ -80,7 +80,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var reac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"initialState\": () => /* binding */ initialState,\n/* harmony export */ \"reducers\": () => /* binding */ reducers\n/* harmony export */ });\n\nvar initialState = {\n user_data: undefined,\n groups_data: undefined,\n manage_groups_modal: false\n};\nvar reducers = function reducers() {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments.length > 1 ? arguments[1] : undefined;\n\n switch (action.type) {\n case \"USER_DATA\":\n return Object.assign({}, state, {\n user_data: action.value\n });\n\n case \"GROUPS_DATA\":\n return Object.assign({}, state, {\n groups_data: action.value\n });\n\n case \"TOGGLE_MANAGE_GROUPS_MODAL\":\n return Object.assign({}, state, {\n manage_groups_modal: !state.manage_groups_modal\n });\n\n default:\n return state;\n }\n};\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/Store.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"initialState\": () => /* binding */ initialState,\n/* harmony export */ \"reducers\": () => /* binding */ reducers\n/* harmony export */ });\n\nvar initialState = {\n user_data: undefined,\n user_page: 0,\n groups_data: undefined,\n groups_page: 0,\n limit: 50,\n manage_groups_modal: false\n};\nvar reducers = function reducers() {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments.length > 1 ? arguments[1] : undefined;\n\n switch (action.type) {\n case \"USER_DATA\":\n return Object.assign({}, state, {\n user_data: action.value\n });\n\n case \"USER_PAGE\":\n return Object.assign({}, state, {\n user_page: action.value.page,\n user_data: action.value.data\n });\n\n case \"GROUPS_DATA\":\n return Object.assign({}, state, {\n groups_data: action.value\n });\n\n case \"TOGGLE_MANAGE_GROUPS_MODAL\":\n return Object.assign({}, state, {\n manage_groups_modal: !state.manage_groups_modal\n });\n\n default:\n return state;\n }\n};\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/Store.js?"); /***/ }), @@ -185,7 +185,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var react_bootstrap__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! react-bootstrap */ \"./node_modules/react-bootstrap/esm/Button.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var react_icons_fa__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! react-icons/fa */ \"./node_modules/react-icons/fa/index.esm.js\");\n/* harmony import */ var _server_dashboard_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./server-dashboard.css */ \"./src/components/ServerDashboard/server-dashboard.css\");\n/* harmony import */ var _util_timeSince__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../util/timeSince */ \"./src/util/timeSince.js\");\n/* harmony import */ var _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { if (typeof Symbol === \"undefined\" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\n\nvar ServerDashboard = function ServerDashboard(props) {\n // sort methods\n var usernameDesc = function usernameDesc(e) {\n return e.sort(function (a, b) {\n return a.name > b.name ? 1 : -1;\n });\n },\n usernameAsc = function usernameAsc(e) {\n return e.sort(function (a, b) {\n return a.name < b.name ? 1 : -1;\n });\n },\n adminDesc = function adminDesc(e) {\n return e.sort(function (a) {\n return a.admin ? -1 : 1;\n });\n },\n adminAsc = function adminAsc(e) {\n return e.sort(function (a) {\n return a.admin ? 1 : -1;\n });\n },\n dateDesc = function dateDesc(e) {\n return e.sort(function (a, b) {\n return new Date(a.last_activity) - new Date(b.last_activity) > 0 ? -1 : 1;\n });\n },\n dateAsc = function dateAsc(e) {\n return e.sort(function (a, b) {\n return new Date(a.last_activity) - new Date(b.last_activity) > 0 ? 1 : -1;\n });\n },\n runningAsc = function runningAsc(e) {\n return e.sort(function (a) {\n return a.server == null ? -1 : 1;\n });\n },\n runningDesc = function runningDesc(e) {\n return e.sort(function (a) {\n return a.server == null ? 1 : -1;\n });\n };\n\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null),\n _useState2 = _slicedToArray(_useState, 2),\n sortMethod = _useState2[0],\n setSortMethod = _useState2[1];\n\n var user_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.user_data;\n });\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useDispatch)();\n var updateUsers = props.updateUsers,\n shutdownHub = props.shutdownHub,\n startServer = props.startServer,\n stopServer = props.stopServer,\n startAll = props.startAll,\n stopAll = props.stopAll,\n history = props.history;\n\n var dispatchUserUpdate = function dispatchUserUpdate(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n if (!user_data) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n }\n\n if (sortMethod != null) {\n user_data = sortMethod(user_data);\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"manage-groups\",\n style: {\n \"float\": \"right\",\n margin: \"20px\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/groups\"\n }, \"> Manage Groups\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"server-dashboard-container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"table\", {\n className: \"table table-striped table-bordered table-hover\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"thead\", {\n className: \"admin-table-head\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"user-header\"\n }, \"User\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: usernameAsc,\n desc: usernameDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"admin-header\"\n }, \"Admin\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: adminAsc,\n desc: adminDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"last-activity-header\"\n }, \"Last Activity\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: dateAsc,\n desc: dateDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"running-status-header\"\n }, \"Running\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: runningAsc,\n desc: runningDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"actions-header\"\n }, \"Actions\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tbody\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", {\n className: \"noborder\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"light\",\n className: \"add-users-button\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/add-users\"\n }, \"Add Users\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"primary\",\n className: \"start-all\",\n onClick: function onClick() {\n Promise.all(startAll(user_data.map(function (e) {\n return e.name;\n }))).then(function (res) {\n updateUsers().then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Start All\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"danger\",\n className: \"stop-all\",\n onClick: function onClick() {\n Promise.all(stopAll(user_data.map(function (e) {\n return e.name;\n }))).then(function (res) {\n updateUsers().then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Stop All\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"danger\",\n id: \"shutdown-button\",\n onClick: shutdownHub\n }, \"Shutdown Hub\"))), user_data.map(function (e, i) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", {\n key: i + \"row\",\n className: \"user-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.admin ? \"admin\" : \"\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.last_activity ? (0,_util_timeSince__WEBPACK_IMPORTED_MODULE_5__.timeSince)(e.last_activity) : \"Never\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.server != null ?\n /*#__PURE__*/\n // Stop Single-user server\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-danger btn-xs stop-button\",\n onClick: function onClick() {\n return stopServer(e.name).then(function (res) {\n updateUsers().then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Stop Server\") :\n /*#__PURE__*/\n // Start Single-user server\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary btn-xs start-button\",\n onClick: function onClick() {\n return startServer(e.name).then(function (res) {\n updateUsers().then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Start Server\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary btn-xs\",\n style: {\n marginRight: 20\n },\n onClick: function onClick() {\n return history.push({\n pathname: \"/edit-user\",\n state: {\n username: e.name,\n has_admin: e.admin\n }\n });\n }\n }, \"edit user\")));\n })))));\n};\n\nServerDashboard.propTypes = {\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n updateUsers: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n shutdownHub: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n startServer: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n stopServer: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n startAll: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n stopAll: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n dispatch: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n history: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n })\n};\n\nvar SortHandler = function SortHandler(props) {\n var sorts = props.sorts,\n callback = props.callback;\n\n var _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState4 = _slicedToArray(_useState3, 2),\n direction = _useState4[0],\n setDirection = _useState4[1];\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"sort-icon\",\n onClick: function onClick() {\n if (!direction) {\n callback(sorts.desc);\n setDirection(\"desc\");\n } else if (direction == \"asc\") {\n callback(sorts.desc);\n setDirection(\"desc\");\n } else {\n callback(sorts.asc);\n setDirection(\"asc\");\n }\n }\n }, !direction ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSort, null) : direction == \"asc\" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSortDown, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSortUp, null));\n};\n\nSortHandler.propTypes = {\n sorts: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ServerDashboard);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/ServerDashboard.jsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var react_bootstrap__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! react-bootstrap */ \"./node_modules/react-bootstrap/esm/Button.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var react_icons_fa__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! react-icons/fa */ \"./node_modules/react-icons/fa/index.esm.js\");\n/* harmony import */ var _server_dashboard_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./server-dashboard.css */ \"./src/components/ServerDashboard/server-dashboard.css\");\n/* harmony import */ var _util_timeSince__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../util/timeSince */ \"./src/util/timeSince.js\");\n/* harmony import */ var _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { if (typeof Symbol === \"undefined\" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\n\n\n\n\nvar ServerDashboard = function ServerDashboard(props) {\n // sort methods\n var usernameDesc = function usernameDesc(e) {\n return e.sort(function (a, b) {\n return a.name > b.name ? 1 : -1;\n });\n },\n usernameAsc = function usernameAsc(e) {\n return e.sort(function (a, b) {\n return a.name < b.name ? 1 : -1;\n });\n },\n adminDesc = function adminDesc(e) {\n return e.sort(function (a) {\n return a.admin ? -1 : 1;\n });\n },\n adminAsc = function adminAsc(e) {\n return e.sort(function (a) {\n return a.admin ? 1 : -1;\n });\n },\n dateDesc = function dateDesc(e) {\n return e.sort(function (a, b) {\n return new Date(a.last_activity) - new Date(b.last_activity) > 0 ? -1 : 1;\n });\n },\n dateAsc = function dateAsc(e) {\n return e.sort(function (a, b) {\n return new Date(a.last_activity) - new Date(b.last_activity) > 0 ? 1 : -1;\n });\n },\n runningAsc = function runningAsc(e) {\n return e.sort(function (a) {\n return a.server == null ? -1 : 1;\n });\n },\n runningDesc = function runningDesc(e) {\n return e.sort(function (a) {\n return a.server == null ? 1 : -1;\n });\n };\n\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null),\n _useState2 = _slicedToArray(_useState, 2),\n sortMethod = _useState2[0],\n setSortMethod = _useState2[1];\n\n var user_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.user_data;\n });\n var user_page = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.user_page;\n });\n var limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.limit;\n });\n var page = parseInt(new URLSearchParams(props.location.search).get(\"page\"));\n page = isNaN(page) ? 0 : page;\n var slice = [page * limit, limit];\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useDispatch)();\n var updateUsers = props.updateUsers,\n shutdownHub = props.shutdownHub,\n startServer = props.startServer,\n stopServer = props.stopServer,\n startAll = props.startAll,\n stopAll = props.stopAll,\n history = props.history;\n\n var dispatchUserUpdate = function dispatchUserUpdate(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n var dispatchPageChange = function dispatchPageChange(data, page) {\n dispatch({\n type: \"USER_PAGE\",\n value: {\n data: data,\n page: page\n }\n });\n };\n\n if (!user_data) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n }\n\n if (page != user_page) {\n updateUsers.apply(void 0, slice).then(function (data) {\n return data.json();\n }).then(function (data) {\n return dispatchPageChange(data, page);\n });\n }\n\n if (sortMethod != null) {\n user_data = sortMethod(user_data);\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"manage-groups\",\n style: {\n \"float\": \"right\",\n margin: \"20px\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/groups\"\n }, \"> Manage Groups\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"server-dashboard-container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"table\", {\n className: \"table table-striped table-bordered table-hover\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"thead\", {\n className: \"admin-table-head\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"user-header\"\n }, \"User\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: usernameAsc,\n desc: usernameDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"admin-header\"\n }, \"Admin\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: adminAsc,\n desc: adminDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"last-activity-header\"\n }, \"Last Activity\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: dateAsc,\n desc: dateDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"running-status-header\"\n }, \"Running\", \" \", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(SortHandler, {\n sorts: {\n asc: runningAsc,\n desc: runningDesc\n },\n callback: function callback(method) {\n return setSortMethod(function () {\n return method;\n });\n }\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"th\", {\n id: \"actions-header\"\n }, \"Actions\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tbody\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", {\n className: \"noborder\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"light\",\n className: \"add-users-button\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/add-users\"\n }, \"Add Users\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"primary\",\n className: \"start-all\",\n onClick: function onClick() {\n Promise.all(startAll(user_data.map(function (e) {\n return e.name;\n }))).then(function (res) {\n updateUsers.apply(void 0, slice).then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Start All\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"danger\",\n className: \"stop-all\",\n onClick: function onClick() {\n Promise.all(stopAll(user_data.map(function (e) {\n return e.name;\n }))).then(function (res) {\n updateUsers.apply(void 0, slice).then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Stop All\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_8__.default, {\n variant: \"danger\",\n id: \"shutdown-button\",\n onClick: shutdownHub\n }, \"Shutdown Hub\"))), user_data.map(function (e, i) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"tr\", {\n key: i + \"row\",\n className: \"user-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.admin ? \"admin\" : \"\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.last_activity ? (0,_util_timeSince__WEBPACK_IMPORTED_MODULE_5__.timeSince)(e.last_activity) : \"Never\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, e.server != null ?\n /*#__PURE__*/\n // Stop Single-user server\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-danger btn-xs stop-button\",\n onClick: function onClick() {\n return stopServer(e.name).then(function (res) {\n updateUsers.apply(void 0, slice).then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Stop Server\") :\n /*#__PURE__*/\n // Start Single-user server\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary btn-xs start-button\",\n onClick: function onClick() {\n return startServer(e.name).then(function (res) {\n updateUsers.apply(void 0, slice).then(function (data) {\n return data.json();\n }).then(function (data) {\n dispatchUserUpdate(data);\n });\n return res;\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Start Server\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary btn-xs\",\n style: {\n marginRight: 20\n },\n onClick: function onClick() {\n return history.push({\n pathname: \"/edit-user\",\n state: {\n username: e.name,\n has_admin: e.admin\n }\n });\n }\n }, \"edit user\")));\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Displaying users \", slice[0], \"-\", slice[0] + user_data.length, user_data.length >= limit ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-link\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/?page=\".concat(page + 1)\n }, \"Next\")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null), page >= 1 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-link\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Link, {\n to: \"/?page=\".concat(page - 1)\n }, \"Previous\")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null)));\n};\n\nServerDashboard.propTypes = {\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n updateUsers: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n shutdownHub: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n startServer: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n stopServer: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n startAll: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n stopAll: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n dispatch: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n history: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n }),\n location: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n search: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().string)\n })\n};\n\nvar SortHandler = function SortHandler(props) {\n var sorts = props.sorts,\n callback = props.callback;\n\n var _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState4 = _slicedToArray(_useState3, 2),\n direction = _useState4[0],\n setDirection = _useState4[1];\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"sort-icon\",\n onClick: function onClick() {\n if (!direction) {\n callback(sorts.desc);\n setDirection(\"desc\");\n } else if (direction == \"asc\") {\n callback(sorts.desc);\n setDirection(\"desc\");\n } else {\n callback(sorts.asc);\n setDirection(\"asc\");\n }\n }\n }, !direction ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSort, null) : direction == \"asc\" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSortDown, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_9__.FaSortUp, null));\n};\n\nSortHandler.propTypes = {\n sorts: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ServerDashboard);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/ServerDashboard.jsx?"); /***/ }), @@ -230,7 +230,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var _jhapiUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./jhapiUtil */ \"./src/util/jhapiUtil.js\");\n\n\nvar withAPI = (0,recompose__WEBPACK_IMPORTED_MODULE_0__.withProps)(function (props) {\n return {\n updateUsers: function updateUsers(cb) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users\", \"GET\");\n },\n shutdownHub: function shutdownHub() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/shutdown\", \"POST\");\n },\n startServer: function startServer(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + name + \"/server\", \"POST\");\n },\n stopServer: function stopServer(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + name + \"/server\", \"DELETE\");\n },\n startAll: function startAll(names) {\n return names.map(function (e) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + e + \"/server\", \"POST\");\n });\n },\n stopAll: function stopAll(names) {\n return names.map(function (e) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + e + \"/server\", \"DELETE\");\n });\n },\n addToGroup: function addToGroup(users, groupname) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupname + \"/users\", \"POST\", {\n users: users\n });\n },\n removeFromGroup: function removeFromGroup(users, groupname) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupname + \"/users\", \"DELETE\", {\n users: users\n });\n },\n createGroup: function createGroup(groupName) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupName, \"POST\");\n },\n deleteGroup: function deleteGroup(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + name, \"DELETE\");\n },\n addUsers: function addUsers(usernames, admin) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users\", \"POST\", {\n usernames: usernames,\n admin: admin\n });\n },\n editUser: function editUser(username, updated_username, admin) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + username, \"PATCH\", {\n name: updated_username,\n admin: admin\n });\n },\n deleteUser: function deleteUser(username) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + username, \"DELETE\");\n },\n failRegexEvent: function failRegexEvent() {\n return alert(\"Cannot change username - either contains special characters or is too short.\");\n },\n noChangeEvent: function noChangeEvent() {\n returns;\n },\n refreshGroupsData: function refreshGroupsData() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups\", \"GET\").then(function (data) {\n return data.json();\n });\n },\n refreshUserData: function refreshUserData() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users\", \"GET\").then(function (data) {\n return data.json();\n });\n }\n };\n});\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (withAPI);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/util/withAPI.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var _jhapiUtil__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./jhapiUtil */ \"./src/util/jhapiUtil.js\");\n\n\nvar withAPI = (0,recompose__WEBPACK_IMPORTED_MODULE_0__.withProps)(function (props) {\n return {\n updateUsers: function updateUsers(offset, limit) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users?offset=\".concat(offset, \"&limit=\").concat(limit), \"GET\");\n },\n shutdownHub: function shutdownHub() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/shutdown\", \"POST\");\n },\n startServer: function startServer(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + name + \"/server\", \"POST\");\n },\n stopServer: function stopServer(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + name + \"/server\", \"DELETE\");\n },\n startAll: function startAll(names) {\n return names.map(function (e) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + e + \"/server\", \"POST\");\n });\n },\n stopAll: function stopAll(names) {\n return names.map(function (e) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + e + \"/server\", \"DELETE\");\n });\n },\n addToGroup: function addToGroup(users, groupname) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupname + \"/users\", \"POST\", {\n users: users\n });\n },\n removeFromGroup: function removeFromGroup(users, groupname) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupname + \"/users\", \"DELETE\", {\n users: users\n });\n },\n createGroup: function createGroup(groupName) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + groupName, \"POST\");\n },\n deleteGroup: function deleteGroup(name) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups/\" + name, \"DELETE\");\n },\n addUsers: function addUsers(usernames, admin) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users\", \"POST\", {\n usernames: usernames,\n admin: admin\n });\n },\n editUser: function editUser(username, updated_username, admin) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + username, \"PATCH\", {\n name: updated_username,\n admin: admin\n });\n },\n deleteUser: function deleteUser(username) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users/\" + username, \"DELETE\");\n },\n failRegexEvent: function failRegexEvent() {\n return alert(\"Cannot change username - either contains special characters or is too short.\");\n },\n noChangeEvent: function noChangeEvent() {\n returns;\n },\n refreshGroupsData: function refreshGroupsData() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups\", \"GET\").then(function (data) {\n return data.json();\n });\n },\n refreshUserData: function refreshUserData() {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/users\", \"GET\").then(function (data) {\n return data.json();\n });\n }\n };\n});\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (withAPI);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/util/withAPI.js?"); /***/ }), @@ -3321,7 +3321,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /******/ /******/ /* webpack/runtime/getFullHash */ /******/ (() => { -/******/ __webpack_require__.h = () => "1d8bd6f06e74c005c433" +/******/ __webpack_require__.h = () => "a33ad3442e1d265c1688" /******/ })(); /******/ /******/ /* webpack/runtime/global */