diff --git a/jsx/build/admin-react.js b/jsx/build/admin-react.js
index 334a7658..55c5f6d7 100644
--- a/jsx/build/admin-react.js
+++ b/jsx/build/admin-react.js
@@ -140,7 +140,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 */ \"CreateGroup\": () => /* binding */ CreateGroup\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Multiselect/Multiselect */ \"./src/components/Multiselect/Multiselect.jsx\");\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\nvar CreateGroup = /*#__PURE__*/function (_Component) {\n _inherits(CreateGroup, _Component);\n\n var _super = _createSuper(CreateGroup);\n\n _createClass(CreateGroup, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\n createGroup: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n refreshGroupsData: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n history: prop_types__WEBPACK_IMPORTED_MODULE_1___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func)\n })\n };\n }\n }]);\n\n function CreateGroup(props) {\n var _this;\n\n _classCallCheck(this, CreateGroup);\n\n _this = _super.call(this, props);\n _this.state = {\n groupName: \"\"\n };\n return _this;\n }\n\n _createClass(CreateGroup, [{\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props = this.props,\n createGroup = _this$props.createGroup,\n refreshGroupsData = _this$props.refreshGroupsData;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel panel-default\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-heading\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"h4\", null, \"Create Group\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"input-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"group-name-input\",\n type: \"text\",\n value: this.state.groupName,\n id: \"group-name\",\n placeholder: \"group name...\",\n onChange: function onChange(e) {\n console.log(e.target.value);\n\n _this2.setState({\n groupName: e.target.value\n });\n }\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"return\",\n className: \"btn btn-light\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_3__.Link, {\n to: \"/\"\n }, \"Back\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"submit\",\n className: \"btn btn-primary\",\n onClick: function onClick() {\n var groupName = _this2.state.groupName;\n createGroup(groupName).then(refreshGroupsData()).then(_this2.props.history.push(\"/groups\"))[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Add Users\")))))));\n }\n }]);\n\n return CreateGroup;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/CreateGroup/CreateGroup.pre.jsx?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CreateGroup\": () => /* binding */ CreateGroup\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Multiselect/Multiselect */ \"./src/components/Multiselect/Multiselect.jsx\");\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\nvar CreateGroup = /*#__PURE__*/function (_Component) {\n _inherits(CreateGroup, _Component);\n\n var _super = _createSuper(CreateGroup);\n\n _createClass(CreateGroup, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\n createGroup: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n refreshGroupsData: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func),\n history: prop_types__WEBPACK_IMPORTED_MODULE_1___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().func)\n })\n };\n }\n }]);\n\n function CreateGroup(props) {\n var _this;\n\n _classCallCheck(this, CreateGroup);\n\n _this = _super.call(this, props);\n _this.state = {\n groupName: \"\"\n };\n return _this;\n }\n\n _createClass(CreateGroup, [{\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props = this.props,\n createGroup = _this$props.createGroup,\n refreshGroupsData = _this$props.refreshGroupsData;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel panel-default\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-heading\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"h4\", null, \"Create Group\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"input-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"group-name-input\",\n type: \"text\",\n value: this.state.groupName,\n id: \"group-name\",\n placeholder: \"group name...\",\n onChange: function onChange(e) {\n _this2.setState({\n groupName: e.target.value\n });\n }\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"return\",\n className: \"btn btn-light\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_3__.Link, {\n to: \"/\"\n }, \"Back\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"submit\",\n className: \"btn btn-primary\",\n onClick: function onClick() {\n var groupName = _this2.state.groupName;\n createGroup(groupName).then(refreshGroupsData()).then(_this2.props.history.push(\"/groups\"))[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Add Users\")))))));\n }\n }]);\n\n return CreateGroup;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/CreateGroup/CreateGroup.pre.jsx?");
/***/ }),
@@ -275,7 +275,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 */ \"ServerDashboard\": () => /* binding */ ServerDashboard\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_bootstrap__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-bootstrap */ \"./node_modules/react-bootstrap/esm/Button.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _server_dashboard_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./server-dashboard.css */ \"./src/components/ServerDashboard/server-dashboard.css\");\n/* harmony import */ var _util_timeSince__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../util/timeSince */ \"./src/util/timeSince.js\");\n/* harmony import */ var react_icons_fa__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react-icons/fa */ \"./node_modules/react-icons/fa/index.esm.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__);\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n\n\nvar ServerDashboard = /*#__PURE__*/function (_Component) {\n _inherits(ServerDashboard, _Component);\n\n var _super = _createSuper(ServerDashboard);\n\n _createClass(ServerDashboard, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\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 }\n }]);\n\n function ServerDashboard(props) {\n var _this;\n\n _classCallCheck(this, ServerDashboard);\n\n _this = _super.call(this, props);\n _this.usernameDesc = function (e) {\n return e.sort(function (a, b) {\n return a.name > b.name ? 1 : -1;\n });\n }, _this.usernameAsc = function (e) {\n return e.sort(function (a, b) {\n return a.name < b.name ? 1 : -1;\n });\n }, _this.adminDesc = function (e) {\n return e.sort(function (a) {\n return a.admin ? -1 : 1;\n });\n }, _this.adminAsc = function (e) {\n return e.sort(function (a) {\n return a.admin ? 1 : -1;\n });\n }, _this.dateDesc = function (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 }, _this.dateAsc = function (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 }, _this.runningAsc = function (e) {\n return e.sort(function (a) {\n return a.server == null ? -1 : 1;\n });\n }, _this.runningDesc = function (e) {\n return e.sort(function (a) {\n return a.server == null ? 1 : -1;\n });\n };\n _this.state = {\n addUser: false,\n sortMethod: undefined\n };\n return _this;\n }\n\n _createClass(ServerDashboard, [{\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props = this.props,\n user_data = _this$props.user_data,\n updateUsers = _this$props.updateUsers,\n shutdownHub = _this$props.shutdownHub,\n startServer = _this$props.startServer,\n stopServer = _this$props.stopServer,\n startAll = _this$props.startAll,\n stopAll = _this$props.stopAll,\n dispatch = _this$props.dispatch;\n\n var dispatchUserUpdate = function dispatchUserUpdate(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n if (!user_data) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n if (this.state.sortMethod != undefined) user_data = this.state.sortMethod(user_data);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null, /*#__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_4__.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: this.usernameAsc,\n desc: this.usernameDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.adminAsc,\n desc: this.adminDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.dateAsc,\n desc: this.dateDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.runningAsc,\n desc: this.runningDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"td\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_5__.default, {\n variant: \"light\",\n className: \"add-users-button\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_4__.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_5__.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_5__.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_5__.default, {\n variant: \"danger\",\n className: \"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_2__.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 _this2.props.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 }]);\n\n return ServerDashboard;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\nvar SortHandler = /*#__PURE__*/function (_Component2) {\n _inherits(SortHandler, _Component2);\n\n var _super2 = _createSuper(SortHandler);\n\n _createClass(SortHandler, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\n sorts: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n };\n }\n }]);\n\n function SortHandler(props) {\n var _this3;\n\n _classCallCheck(this, SortHandler);\n\n _this3 = _super2.call(this, props);\n _this3.state = {\n direction: undefined\n };\n return _this3;\n }\n\n _createClass(SortHandler, [{\n key: \"render\",\n value: function render() {\n var _this4 = this;\n\n var _this$props2 = this.props,\n sorts = _this$props2.sorts,\n callback = _this$props2.callback;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"sort-icon\",\n onClick: function onClick() {\n if (!_this4.state.direction) {\n callback(sorts.desc);\n\n _this4.setState({\n direction: \"desc\"\n });\n } else if (_this4.state.direction == \"asc\") {\n callback(sorts.desc);\n\n _this4.setState({\n direction: \"desc\"\n });\n } else {\n callback(sorts.asc);\n\n _this4.setState({\n direction: \"asc\"\n });\n }\n }\n }, !this.state.direction ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSort, null) : this.state.direction == \"asc\" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSortDown, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSortUp, null));\n }\n }]);\n\n return SortHandler;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/ServerDashboard.pre.jsx?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ServerDashboard\": () => /* binding */ ServerDashboard\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react_bootstrap__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-bootstrap */ \"./node_modules/react-bootstrap/esm/Button.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _server_dashboard_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./server-dashboard.css */ \"./src/components/ServerDashboard/server-dashboard.css\");\n/* harmony import */ var _util_timeSince__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../util/timeSince */ \"./src/util/timeSince.js\");\n/* harmony import */ var react_icons_fa__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react-icons/fa */ \"./node_modules/react-icons/fa/index.esm.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__);\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n\n\nvar ServerDashboard = /*#__PURE__*/function (_Component) {\n _inherits(ServerDashboard, _Component);\n\n var _super = _createSuper(ServerDashboard);\n\n _createClass(ServerDashboard, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\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 }\n }]);\n\n function ServerDashboard(props) {\n var _this;\n\n _classCallCheck(this, ServerDashboard);\n\n _this = _super.call(this, props);\n _this.usernameDesc = function (e) {\n return e.sort(function (a, b) {\n return a.name > b.name ? 1 : -1;\n });\n }, _this.usernameAsc = function (e) {\n return e.sort(function (a, b) {\n return a.name < b.name ? 1 : -1;\n });\n }, _this.adminDesc = function (e) {\n return e.sort(function (a) {\n return a.admin ? -1 : 1;\n });\n }, _this.adminAsc = function (e) {\n return e.sort(function (a) {\n return a.admin ? 1 : -1;\n });\n }, _this.dateDesc = function (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 }, _this.dateAsc = function (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 }, _this.runningAsc = function (e) {\n return e.sort(function (a) {\n return a.server == null ? -1 : 1;\n });\n }, _this.runningDesc = function (e) {\n return e.sort(function (a) {\n return a.server == null ? 1 : -1;\n });\n };\n _this.state = {\n addUser: false,\n sortMethod: undefined\n };\n return _this;\n }\n\n _createClass(ServerDashboard, [{\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props = this.props,\n user_data = _this$props.user_data,\n updateUsers = _this$props.updateUsers,\n shutdownHub = _this$props.shutdownHub,\n startServer = _this$props.startServer,\n stopServer = _this$props.stopServer,\n startAll = _this$props.startAll,\n stopAll = _this$props.stopAll,\n dispatch = _this$props.dispatch;\n\n var dispatchUserUpdate = function dispatchUserUpdate(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n if (!user_data) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n if (this.state.sortMethod != undefined) user_data = this.state.sortMethod(user_data);\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_4__.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: this.usernameAsc,\n desc: this.usernameDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.adminAsc,\n desc: this.adminDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.dateAsc,\n desc: this.dateDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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: this.runningAsc,\n desc: this.runningDesc\n },\n callback: function callback(e) {\n return _this2.setState(Object.assign({}, _this2.state, {\n sortMethod: e\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_5__.default, {\n variant: \"light\",\n className: \"add-users-button\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_4__.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_5__.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_5__.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_5__.default, {\n variant: \"danger\",\n className: \"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_2__.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 _this2.props.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 }]);\n\n return ServerDashboard;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\nvar SortHandler = /*#__PURE__*/function (_Component2) {\n _inherits(SortHandler, _Component2);\n\n var _super2 = _createSuper(SortHandler);\n\n _createClass(SortHandler, null, [{\n key: \"propTypes\",\n get: function get() {\n return {\n sorts: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n };\n }\n }]);\n\n function SortHandler(props) {\n var _this3;\n\n _classCallCheck(this, SortHandler);\n\n _this3 = _super2.call(this, props);\n _this3.state = {\n direction: undefined\n };\n return _this3;\n }\n\n _createClass(SortHandler, [{\n key: \"render\",\n value: function render() {\n var _this4 = this;\n\n var _this$props2 = this.props,\n sorts = _this$props2.sorts,\n callback = _this$props2.callback;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"sort-icon\",\n onClick: function onClick() {\n if (!_this4.state.direction) {\n callback(sorts.desc);\n\n _this4.setState({\n direction: \"desc\"\n });\n } else if (_this4.state.direction == \"asc\") {\n callback(sorts.desc);\n\n _this4.setState({\n direction: \"desc\"\n });\n } else {\n callback(sorts.asc);\n\n _this4.setState({\n direction: \"asc\"\n });\n }\n }\n }, !this.state.direction ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSort, null) : this.state.direction == \"asc\" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSortDown, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_6__.FaSortUp, null));\n }\n }]);\n\n return SortHandler;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/ServerDashboard.pre.jsx?");
/***/ }),
@@ -365,7 +365,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ ((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 _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_style_root_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js!../../style/root.css */ \"./node_modules/css-loader/dist/cjs.js!./src/style/root.css\");\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_style_root_css__WEBPACK_IMPORTED_MODULE_1__.default);\n// Module\n___CSS_LOADER_EXPORT___.push([module.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: .125em;\\n position: relative;\\n user-select: none;\\n cursor: pointer;\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/server-dashboard.css?./node_modules/css-loader/dist/cjs.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 _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_style_root_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js!../../style/root.css */ \"./node_modules/css-loader/dist/cjs.js!./src/style/root.css\");\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n___CSS_LOADER_EXPORT___.i(_node_modules_css_loader_dist_cjs_js_style_root_css__WEBPACK_IMPORTED_MODULE_1__.default);\n// Module\n___CSS_LOADER_EXPORT___.push([module.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: .125em;\\n position: relative;\\n user-select: none;\\n cursor: pointer;\\n}\\n\\ntr.noborder > td {\\n border: none !important;\\n width: auto\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/ServerDashboard/server-dashboard.css?./node_modules/css-loader/dist/cjs.js");
/***/ }),
@@ -3416,7 +3416,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
-/******/ __webpack_require__.h = () => "cf7cb68db8ca626e6bc6"
+/******/ __webpack_require__.h = () => "e3ffa410672a689f4a87"
/******/ })();
/******/
/******/ /* webpack/runtime/global */
diff --git a/jsx/src/components/ServerDashboard/ServerDashboard.pre.jsx b/jsx/src/components/ServerDashboard/ServerDashboard.pre.jsx
index 97d57ed8..fbc1e532 100644
--- a/jsx/src/components/ServerDashboard/ServerDashboard.pre.jsx
+++ b/jsx/src/components/ServerDashboard/ServerDashboard.pre.jsx
@@ -72,7 +72,7 @@ export class ServerDashboard extends Component {
user_data = this.state.sortMethod(user_data);
return (
-
+
-
+
|