diff --git a/jsx/README.md b/jsx/README.md index 81ce206e..a172cdaf 100644 --- a/jsx/README.md +++ b/jsx/README.md @@ -12,3 +12,53 @@ admin dashboard codebase. - `yarn lint`: Lints JSX with ESLint - `yarn lint --fix`: Lints and fixes errors JSX with ESLint / formats with Prettier - `yarn place`: Copies the transpiled React bundle to /share/jupyterhub/static/js/admin-react.js for use. + +### Good To Know + +Just some basics on how the React Admin app is built. + +#### General build structure: + +This app is written in JSX, and then transpiled into an ES5 bundle with Babel and Webpack. All JSX components are unit tested with a mixture of Jest and Enzyme and can be run both manually and per-commit. Most logic is separated into components under the `/src/components` directory, each directory containing a `.jsx`, `.test.jsx`, and sometimes a `.css` file. These components are all pulled together, given client-side routes, and connected to the Redux store in `/src/App.jsx` which serves as an entrypoint to the application. + +#### Centralized state and data management with Redux: + +The app use Redux throughout the components via the `useSelector` and `useDispatch` hooks to store and update user and group data from the API. With Redux, this data is available to any connected component. This means that if one component recieves new data, they all do. + +### API functions + +All API functions used by the front end are packaged as a library of props within `/src/util/withAPI.js`. This keeps our web service logic separate from our presentational logic, allowing us to connect API functionality to our components at a high level and keep the code more modular. This connection specifically happens in `/src/App.jsx`, within the route assignments. + +### Pagination + +Indicies of paginated user and group data is stored in a `page` variable in the query string, as well as the `user_page` / `group_page` state variables in Redux. This allows the app to maintain two sources of truth, as well as protect the admin user's place in the collection on page reload. Limit is constant at this point and is held in the Redux state. + +On updates to the paginated data, the app can respond in one of two ways. If a user/group record is either added or deleted, the pagination will reset and data will be pulled back with no offset. Alternatively, if a record is modified, the offset will remain and the change will be shown. + +Code examples: + +```js +// Pagination limit is pulled in from Redux. +var limit = useSelector((state) => state.limit); + +// Page query string is parsed and checked +var page = parseInt(new URLQuerySearch(props.location).get("page")); +page = isNaN(page) ? 0 : page; + +// A slice is created representing the records to be returned +var slice = [page * limit, limit]; + +// A user's notebook server status was changed from stopped to running, user data is being refreshed from the slice. +startServer().then(() => { + updateUsers(...slice) + // After data is fetched, the Redux store is updated with the data and a copy of the page number. + .then((data) => dispatchPageChange(data, page)); +}); + +// Alternatively, a new user was added, user data is being refreshed from offset 0. +addUser().then(() => { + updateUsers(0, limit) + // After data is fetched, the Redux store is updated with the data and asserts page 0. + .then((data) => dispatchPageChange(data, 0)); +}); +``` diff --git a/jsx/src/Store.js b/jsx/src/Store.js index fa1824ac..8ac8a5bb 100644 --- a/jsx/src/Store.js +++ b/jsx/src/Store.js @@ -5,25 +5,33 @@ export const initialState = { user_page: 0, groups_data: undefined, groups_page: 0, - limit: 50, - manage_groups_modal: false, + limit: 3, }; export const reducers = (state = initialState, action) => { switch (action.type) { - case "USER_DATA": - return Object.assign({}, state, { user_data: action.value }); + // Updates the client user model data and stores the page case "USER_PAGE": return Object.assign({}, state, { user_page: action.value.page, user_data: action.value.data, }); + + // Deprecated - doesn't store pagination values + case "USER_DATA": + return Object.assign({}, state, { user_data: action.value }); + + // Updates the client group model data and stores the page + case "GROUPS_PAGE": + return Object.assign({}, state, { + groups_page: action.value.page, + groups_data: action.value.data, + }); + + // Deprecated - doesn't store pagination values case "GROUPS_DATA": return Object.assign({}, state, { groups_data: action.value }); - case "TOGGLE_MANAGE_GROUPS_MODAL": - return Object.assign({}, state, { - manage_groups_modal: !state.manage_groups_modal, - }); + default: return state; } diff --git a/jsx/src/TODO b/jsx/src/TODO new file mode 100644 index 00000000..25754ead --- /dev/null +++ b/jsx/src/TODO @@ -0,0 +1 @@ +- When changing route with nothing edited, pass user_data / group_data through location to maintain spot diff --git a/jsx/src/components/AddUser/AddUser.jsx b/jsx/src/components/AddUser/AddUser.jsx index 5407e566..2518361d 100644 --- a/jsx/src/components/AddUser/AddUser.jsx +++ b/jsx/src/components/AddUser/AddUser.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { useDispatch } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import { compose, withProps } from "recompose"; import { Link } from "react-router-dom"; import PropTypes from "prop-types"; @@ -7,18 +7,22 @@ import { jhapiRequest } from "../../util/jhapiUtil"; const AddUser = (props) => { var [users, setUsers] = useState([]), - [admin, setAdmin] = useState(false); + [admin, setAdmin] = useState(false), + limit = useSelector((state) => state.limit); var dispatch = useDispatch(); - var dispatchUserData = (data) => { + var dispatchPageChange = (data, page) => { dispatch({ - type: "USER_DATA", - value: data, + type: "USER_PAGE", + value: { + data: data, + page: page, + }, }); }; - var { addUsers, failRegexEvent, refreshUserData, history } = props; + var { addUsers, failRegexEvent, updateUsers, history } = props; return ( <> @@ -78,12 +82,12 @@ const AddUser = (props) => { } addUsers(filtered_users, admin) - .then( - refreshUserData() - .then((data) => dispatchUserData(data)) + .then(() => + updateUsers(0, limit) + .then((data) => dispatchPageChange(data, 0)) + .then(() => history.push("/")) .catch((err) => console.log(err)) ) - .then(() => history.push("/")) .catch((err) => console.log(err)); }} > @@ -101,7 +105,7 @@ const AddUser = (props) => { AddUser.propTypes = { addUsers: PropTypes.func, failRegexEvent: PropTypes.func, - refreshUserData: PropTypes.func, + updateUsers: PropTypes.func, history: PropTypes.shape({ push: PropTypes.func, }), diff --git a/jsx/src/components/CreateGroup/CreateGroup.jsx b/jsx/src/components/CreateGroup/CreateGroup.jsx index 431c2e18..46c56cd7 100644 --- a/jsx/src/components/CreateGroup/CreateGroup.jsx +++ b/jsx/src/components/CreateGroup/CreateGroup.jsx @@ -1,23 +1,25 @@ import React, { useState } from "react"; -import { useDispatch } from "react-redux"; -import { compose, withProps } from "recompose"; +import { useDispatch, useSelector } from "react-redux"; import { Link } from "react-router-dom"; import PropTypes from "prop-types"; -import { jhapiRequest } from "../../util/jhapiUtil"; const CreateGroup = (props) => { - var [groupName, setGroupName] = useState(""); + var [groupName, setGroupName] = useState(""), + limit = useSelector((state) => state.limit); var dispatch = useDispatch(); - var dispatchGroupsData = (data) => { + var dispatchPageUpdate = (data, page) => { dispatch({ type: "GROUPS_DATA", - value: data, + value: { + data: data, + page: page, + }, }); }; - var { createGroup, refreshGroupsData, history } = props; + var { createGroup, updateGroups, history } = props; return ( <> @@ -53,11 +55,11 @@ const CreateGroup = (props) => { onClick={() => { createGroup(groupName) .then( - refreshGroupsData() - .then((data) => dispatchGroupsData(data)) + updateGroups(0, limit) + .then((data) => dispatchPageUpdate(data, 0)) + .then(history.push("/groups")) .catch((err) => console.log(err)) ) - .then(history.push("/groups")) .catch((err) => console.log(err)); }} > @@ -74,7 +76,7 @@ const CreateGroup = (props) => { CreateGroup.propTypes = { createGroup: PropTypes.func, - refreshGroupsData: PropTypes.func, + updateGroups: PropTypes.func, failRegexEvent: PropTypes.func, history: PropTypes.shape({ push: PropTypes.func, diff --git a/jsx/src/components/EditUser/EditUser.jsx b/jsx/src/components/EditUser/EditUser.jsx index 26d52543..929d09b0 100644 --- a/jsx/src/components/EditUser/EditUser.jsx +++ b/jsx/src/components/EditUser/EditUser.jsx @@ -1,15 +1,20 @@ import React, { useState } from "react"; -import { useDispatch } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import PropTypes from "prop-types"; import { Link } from "react-router-dom"; const EditUser = (props) => { + var limit = useSelector((state) => state.limit); + var dispatch = useDispatch(); - var dispatchUserData = (data) => { + var dispatchPageChange = (data, page) => { dispatch({ - type: "USER_DATA", - value: data, + type: "USER_PAGE", + value: { + data: data, + page: page, + }, }); }; @@ -18,7 +23,7 @@ const EditUser = (props) => { deleteUser, failRegexEvent, noChangeEvent, - refreshUserData, + updateUsers, history, } = props; @@ -70,9 +75,9 @@ const EditUser = (props) => { onClick={() => { deleteUser(username) .then((data) => { - history.push("/"); - refreshUserData() - .then((data) => dispatchUserData(data)) + updateUsers(0, limit) + .then((data) => dispatchPageChange(data, 0)) + .then(() => history.push("/")) .catch((err) => console.log(err)); }) .catch((err) => console.log(err)); @@ -106,9 +111,9 @@ const EditUser = (props) => { admin ) .then((data) => { - history.push("/"); - refreshUserData() - .then((data) => dispatchUserData(data)) + updateUsers(0, limit) + .then((data) => dispatchPageChange(data, 0)) + .then(() => history.push("/")) .catch((err) => console.log(err)); }) .catch((err) => {}); @@ -119,9 +124,9 @@ const EditUser = (props) => { } else { editUser(username, username, admin) .then((data) => { - history.push("/"); - refreshUserData() - .then((data) => dispatchUserData(data)) + updateUsers(0, limit) + .then((data) => dispatchPageChange(data, 0)) + .then(() => history.push("/")) .catch((err) => console.log(err)); }) .catch((err) => {}); @@ -153,7 +158,7 @@ EditUser.propTypes = { deleteUser: PropTypes.func, failRegexEvent: PropTypes.func, noChangeEvent: PropTypes.func, - refreshUserData: PropTypes.func, + updateUsers: PropTypes.func, }; export default EditUser; diff --git a/jsx/src/components/GroupEdit/GroupEdit.jsx b/jsx/src/components/GroupEdit/GroupEdit.jsx index 3e226706..8666959a 100644 --- a/jsx/src/components/GroupEdit/GroupEdit.jsx +++ b/jsx/src/components/GroupEdit/GroupEdit.jsx @@ -10,14 +10,18 @@ const GroupEdit = (props) => { var [selected, setSelected] = useState([]), [changed, setChanged] = useState(false), [added, setAdded] = useState(undefined), - [removed, setRemoved] = useState(undefined); + [removed, setRemoved] = useState(undefined), + limit = useSelector((state) => state.limit); var dispatch = useDispatch(); - const dispatchGroupsData = (data) => { + const dispatchPageUpdate = (data, page) => { dispatch({ - type: "GROUPS_DATA", - value: data, + type: "GROUPS_PAGE", + value: { + data: data, + page: page, + }, }); }; @@ -25,7 +29,7 @@ const GroupEdit = (props) => { addToGroup, removeFromGroup, deleteGroup, - refreshGroupsData, + updateGroups, history, location, } = props; @@ -88,10 +92,12 @@ const GroupEdit = (props) => { ); Promise.all(promiseQueue) - .then((e) => callback()) + .then((e) => { + updateGroups(0, limit) + .then((data) => dispatchPageUpdate(data, 0)) + .then(() => history.push("/groups")); + }) .catch((err) => console.log(err)); - - history.push("/groups"); }} > Apply @@ -103,10 +109,11 @@ const GroupEdit = (props) => { onClick={() => { var groupName = group_data.name; deleteGroup(groupName) - .then( - refreshGroupsData().then((data) => dispatchGroupsData(data)) - ) - .then(history.push("/groups")) + .then((e) => { + updateGroups(0, limit) + .then((data) => dispatchPageUpdate(data, 0)) + .then(() => history.push("/groups")); + }) .catch((err) => console.log(err)); }} > @@ -134,7 +141,7 @@ GroupEdit.propTypes = { addToGroup: PropTypes.func, removeFromGroup: PropTypes.func, deleteGroup: PropTypes.func, - refreshGroupsData: PropTypes.func, + updateGroups: PropTypes.func, }; export default GroupEdit; diff --git a/jsx/src/components/Groups/Groups.jsx b/jsx/src/components/Groups/Groups.jsx index 7465141d..14a768f1 100644 --- a/jsx/src/components/Groups/Groups.jsx +++ b/jsx/src/components/Groups/Groups.jsx @@ -4,32 +4,41 @@ import { compose, withProps } from "recompose"; import PropTypes from "prop-types"; import { Link } from "react-router-dom"; -import { jhapiRequest } from "../../util/jhapiUtil"; +import PaginationFooter from "../PaginationFooter/PaginationFooter"; const Groups = (props) => { var user_data = useSelector((state) => state.user_data), groups_data = useSelector((state) => state.groups_data), - dispatch = useDispatch(); + groups_page = useSelector((state) => state.groups_page), + user_page = useSelector((state) => state.user_page), + limit = useSelector((state) => state.limit), + dispatch = useDispatch(), + page = parseInt(new URLSearchParams(props.location.search).get("page")); - var { refreshGroupsData, refreshUserData, history } = props; + page = isNaN(page) ? 0 : page; + var slice = [page * limit, limit]; + + var { updateGroups, history } = props; if (!groups_data || !user_data) { return
; } - const dispatchGroupsData = (data) => { + const dispatchPageChange = (data, page) => { dispatch({ - type: "GROUPS_DATA", - value: data, + type: "GROUPS_PAGE", + value: { + data: data, + page: page, + }, }); }; - const dispatchUserData = (data) => { - dispatch({ - type: "USER_DATA", - value: data, + if (groups_page != page) { + updateGroups(...slice).then((data) => { + dispatchPageChange(data, page); }); - }; + } return (
@@ -40,37 +49,39 @@ const Groups = (props) => {

Groups

- {groups_data.length > 0 ? ( - groups_data.map((e, i) => ( -
-

+
    + {groups_data.length > 0 ? ( + groups_data.map((e, i) => ( +
  • + + {e.users.length + " users"} + { - refreshGroupsData() - .then((data) => dispatchGroupsData(data)) - .catch((err) => console.log(err)); - refreshUserData() - .then((data) => dispatchUserData(data)) - .catch((err) => console.log(err)); - }, }, }} > {e.name} -

+ + )) + ) : ( +
+

no groups created...

- )) - ) : ( -
-

no groups created...

-
- )} + )} + +
+ ) : ( + + )} + {numElements >= limit ? ( + + ) : ( + + )} +

+
+ ); +}; + +PaginationFooter.propTypes = { + endpoint: PropTypes.string, + page: PropTypes.number, + limit: PropTypes.number, + numOffset: PropTypes.number, + numElements: PropTypes.number, +}; + +export default PaginationFooter; diff --git a/jsx/src/components/PaginationFooter/pagination-footer.css b/jsx/src/components/PaginationFooter/pagination-footer.css new file mode 100644 index 00000000..a764dfc9 --- /dev/null +++ b/jsx/src/components/PaginationFooter/pagination-footer.css @@ -0,0 +1,14 @@ +@import url(../../style/root.css); + +.pagination-footer * button { + margin-right: 10px; +} + +.pagination-footer * .inactive-pagination { + color: gray; + cursor: not-allowed; +} + +.pagination-footer * button.spaced { + color: var(--blue); +} diff --git a/jsx/src/components/ServerDashboard/ServerDashboard.jsx b/jsx/src/components/ServerDashboard/ServerDashboard.jsx index f8dd3fd6..35f161f8 100644 --- a/jsx/src/components/ServerDashboard/ServerDashboard.jsx +++ b/jsx/src/components/ServerDashboard/ServerDashboard.jsx @@ -10,6 +10,7 @@ import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa"; import "./server-dashboard.css"; import { timeSince } from "../../util/timeSince"; import { jhapiRequest } from "../../util/jhapiUtil"; +import PaginationFooter from "../PaginationFooter/PaginationFooter"; const ServerDashboard = (props) => { // sort methods @@ -30,10 +31,13 @@ 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")); + var user_data = useSelector((state) => state.user_data), + user_page = useSelector((state) => state.user_page), + limit = useSelector((state) => state.limit), + page = parseInt(new URLSearchParams(props.location.search).get("page")); + + console.log(user_page); + page = isNaN(page) ? 0 : page; var slice = [page * limit, limit]; @@ -49,14 +53,7 @@ const ServerDashboard = (props) => { history, } = props; - var dispatchUserUpdate = (data) => { - dispatch({ - type: "USER_DATA", - value: data, - }); - }; - - var dispatchPageChange = (data, page) => { + var dispatchPageUpdate = (data, page) => { dispatch({ type: "USER_PAGE", value: { @@ -71,9 +68,7 @@ const ServerDashboard = (props) => { } if (page != user_page) { - updateUsers(...slice) - .then((data) => data.json()) - .then((data) => dispatchPageChange(data, page)); + updateUsers(...slice).then((data) => dispatchPageUpdate(data, page)); } if (sortMethod != null) { @@ -138,9 +133,8 @@ const ServerDashboard = (props) => { Promise.all(startAll(user_data.map((e) => e.name))) .then((res) => { updateUsers(...slice) - .then((data) => data.json()) .then((data) => { - dispatchUserUpdate(data); + dispatchPageUpdate(data, page); }) .catch((err) => console.log(err)); return res; @@ -159,9 +153,8 @@ const ServerDashboard = (props) => { Promise.all(stopAll(user_data.map((e) => e.name))) .then((res) => { updateUsers(...slice) - .then((data) => data.json()) .then((data) => { - dispatchUserUpdate(data); + dispatchPageUpdate(data, page); }) .catch((err) => console.log(err)); return res; @@ -198,11 +191,9 @@ const ServerDashboard = (props) => { onClick={() => stopServer(e.name) .then((res) => { - updateUsers(...slice) - .then((data) => data.json()) - .then((data) => { - dispatchUserUpdate(data); - }); + updateUsers(...slice).then((data) => { + dispatchPageUpdate(data, page); + }); return res; }) .catch((err) => console.log(err)) @@ -217,11 +208,9 @@ const ServerDashboard = (props) => { onClick={() => startServer(e.name) .then((res) => { - updateUsers(...slice) - .then((data) => data.json()) - .then((data) => { - dispatchUserUpdate(data); - }); + updateUsers(...slice).then((data) => { + dispatchPageUpdate(data, page); + }); return res; }) .catch((err) => console.log(err)) @@ -253,24 +242,13 @@ const ServerDashboard = (props) => { ))} -

-

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

+

diff --git a/jsx/src/style/root.css b/jsx/src/style/root.css index feeb2c16..8adb8e40 100644 --- a/jsx/src/style/root.css +++ b/jsx/src/style/root.css @@ -3,7 +3,7 @@ --orange: #f1ad4e; --blue: #2e7ab6; --white: #ffffff; - --gray: #f7f7f; + --gray: #f7f7f7; } /* Color Classes */ diff --git a/jsx/src/util/withAPI.js b/jsx/src/util/withAPI.js index 4896db10..4ff1a0f5 100644 --- a/jsx/src/util/withAPI.js +++ b/jsx/src/util/withAPI.js @@ -3,7 +3,14 @@ import { jhapiRequest } from "./jhapiUtil"; const withAPI = withProps((props) => ({ updateUsers: (offset, limit) => - jhapiRequest(`/users?offset=${offset}&limit=${limit}`, "GET"), + jhapiRequest(`/users?offset=${offset}&limit=${limit}`, "GET").then((data) => + data.json() + ), + updateGroups: (offset, limit) => + jhapiRequest( + `/groups?offset=${offset}&limit=${limit}`, + "GET" + ).then((data) => data.json()), 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 7104c677..247ab5c7 100644 --- a/share/jupyterhub/static/js/admin-react.js +++ b/share/jupyterhub/static/js/admin-react.js @@ -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 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?"); +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: 3\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 // Updates the client user model data and stores the page\n case \"USER_PAGE\":\n return Object.assign({}, state, {\n user_page: action.value.page,\n user_data: action.value.data\n });\n // Deprecated - doesn't store pagination values\n\n case \"USER_DATA\":\n return Object.assign({}, state, {\n user_data: action.value\n });\n // Updates the client group model data and stores the page\n\n case \"GROUPS_PAGE\":\n return Object.assign({}, state, {\n groups_page: action.value.page,\n groups_data: action.value.data\n });\n // Deprecated - doesn't store pagination values\n\n case \"GROUPS_DATA\":\n return Object.assign({}, state, {\n groups_data: action.value\n });\n\n default:\n return state;\n }\n};\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/Store.js?"); /***/ }), @@ -95,7 +95,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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.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 _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __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\nvar AddUser = function AddUser(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]),\n _useState2 = _slicedToArray(_useState, 2),\n users = _useState2[0],\n setUsers = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),\n _useState4 = _slicedToArray(_useState3, 2),\n admin = _useState4[0],\n setAdmin = _useState4[1];\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchUserData = function dispatchUserData(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n var addUsers = props.addUsers,\n failRegexEvent = props.failRegexEvent,\n refreshUserData = props.refreshUserData,\n history = props.history;\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, \"Add Users\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"form\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"textarea\", {\n className: \"form-control\",\n id: \"add-user-textarea\",\n rows: \"3\",\n placeholder: \"usernames separated by line\",\n onBlur: function onBlur(e) {\n var split_users = e.target.value.split(\"\\n\");\n setUsers(split_users);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"form-check-input\",\n type: \"checkbox\",\n value: \"\",\n id: \"admin-check\",\n onChange: function onChange(e) {\n return setAdmin(e.target.checked);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"label\", {\n className: \"form-check-label\"\n }, \"Admin\")))), /*#__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_5__.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 filtered_users = users.filter(function (e) {\n return e.length > 2 && /[!@#$%^&*(),.?\":{}|<>]/g.test(e) == false;\n });\n\n if (filtered_users.length < users.length) {\n var removed_users = users.filter(function (e) {\n return !filtered_users.includes(e);\n });\n setUsers(filtered_users);\n failRegexEvent();\n }\n\n addUsers(filtered_users, admin).then(refreshUserData().then(function (data) {\n return dispatchUserData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n })).then(function () {\n return history.push(\"/\");\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Add Users\")))))));\n};\n\nAddUser.propTypes = {\n addUsers: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n refreshUserData: (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/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AddUser);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/AddUser/AddUser.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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.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 _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __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\nvar AddUser = function AddUser(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]),\n _useState2 = _slicedToArray(_useState, 2),\n users = _useState2[0],\n setUsers = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),\n _useState4 = _slicedToArray(_useState3, 2),\n admin = _useState4[0],\n setAdmin = _useState4[1],\n limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.limit;\n });\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\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 var addUsers = props.addUsers,\n failRegexEvent = props.failRegexEvent,\n updateUsers = props.updateUsers,\n history = props.history;\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, \"Add Users\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"form\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"textarea\", {\n className: \"form-control\",\n id: \"add-user-textarea\",\n rows: \"3\",\n placeholder: \"usernames separated by line\",\n onBlur: function onBlur(e) {\n var split_users = e.target.value.split(\"\\n\");\n setUsers(split_users);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"form-check-input\",\n type: \"checkbox\",\n value: \"\",\n id: \"admin-check\",\n onChange: function onChange(e) {\n return setAdmin(e.target.checked);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"label\", {\n className: \"form-check-label\"\n }, \"Admin\")))), /*#__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_5__.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 filtered_users = users.filter(function (e) {\n return e.length > 2 && /[!@#$%^&*(),.?\":{}|<>]/g.test(e) == false;\n });\n\n if (filtered_users.length < users.length) {\n var removed_users = users.filter(function (e) {\n return !filtered_users.includes(e);\n });\n setUsers(filtered_users);\n failRegexEvent();\n }\n\n addUsers(filtered_users, admin).then(function () {\n return updateUsers(0, limit).then(function (data) {\n return dispatchPageChange(data, 0);\n }).then(function () {\n return history.push(\"/\");\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Add Users\")))))));\n};\n\nAddUser.propTypes = {\n addUsers: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n updateUsers: (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/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AddUser);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/AddUser/AddUser.jsx?"); /***/ }), @@ -110,7 +110,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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.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 _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __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\nvar CreateGroup = function CreateGroup(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\"),\n _useState2 = _slicedToArray(_useState, 2),\n groupName = _useState2[0],\n setGroupName = _useState2[1];\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchGroupsData = function dispatchGroupsData(data) {\n dispatch({\n type: \"GROUPS_DATA\",\n value: data\n });\n };\n\n var createGroup = props.createGroup,\n refreshGroupsData = props.refreshGroupsData,\n history = props.history;\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 id: \"group-name\",\n value: groupName,\n placeholder: \"group name...\",\n onChange: function onChange(e) {\n setGroupName(e.target.value);\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_5__.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 createGroup(groupName).then(refreshGroupsData().then(function (data) {\n return dispatchGroupsData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n })).then(history.push(\"/groups\"))[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Create\")))))));\n};\n\nCreateGroup.propTypes = {\n createGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n refreshGroupsData: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n failRegexEvent: (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/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CreateGroup);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/CreateGroup/CreateGroup.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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/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_2__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_2__);\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\nvar CreateGroup = function CreateGroup(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\"),\n _useState2 = _slicedToArray(_useState, 2),\n groupName = _useState2[0],\n setGroupName = _useState2[1],\n limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.limit;\n });\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchPageUpdate = function dispatchPageUpdate(data, page) {\n dispatch({\n type: \"GROUPS_DATA\",\n value: {\n data: data,\n page: page\n }\n });\n };\n\n var createGroup = props.createGroup,\n updateGroups = props.updateGroups,\n history = props.history;\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 id: \"group-name\",\n value: groupName,\n placeholder: \"group name...\",\n onChange: function onChange(e) {\n setGroupName(e.target.value);\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 createGroup(groupName).then(updateGroups(0, limit).then(function (data) {\n return dispatchPageUpdate(data, 0);\n }).then(history.push(\"/groups\"))[\"catch\"](function (err) {\n return console.log(err);\n }))[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Create\")))))));\n};\n\nCreateGroup.propTypes = {\n createGroup: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n updateGroups: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n history: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func)\n })\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CreateGroup);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/CreateGroup/CreateGroup.jsx?"); /***/ }), @@ -125,7 +125,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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_2__);\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\");\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\nvar EditUser = function EditUser(props) {\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchUserData = function dispatchUserData(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\n };\n\n var editUser = props.editUser,\n deleteUser = props.deleteUser,\n failRegexEvent = props.failRegexEvent,\n noChangeEvent = props.noChangeEvent,\n refreshUserData = props.refreshUserData,\n history = props.history;\n\n if (props.location.state == undefined) {\n props.history.push(\"/\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n\n var _props$location$state = props.location.state,\n username = _props$location$state.username,\n has_admin = _props$location$state.has_admin;\n\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\"),\n _useState2 = _slicedToArray(_useState, 2),\n updatedUsername = _useState2[0],\n setUpdatedUsername = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(has_admin),\n _useState4 = _slicedToArray(_useState3, 2),\n admin = _useState4[0],\n setAdmin = _useState4[1];\n\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, \"Editing user \", username)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"form\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"textarea\", {\n className: \"form-control\",\n id: \"exampleFormControlTextarea1\",\n rows: \"3\",\n placeholder: \"updated username\",\n onBlur: function onBlur(e) {\n setUpdatedUsername(e.target.value);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"form-check-input\",\n checked: admin,\n type: \"checkbox\",\n id: \"admin-check\",\n onChange: function onChange(e) {\n return setAdmin(!admin);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"label\", {\n className: \"form-check-label\"\n }, \"Admin\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"delete-user\",\n className: \"btn btn-danger btn-sm\",\n onClick: function onClick() {\n deleteUser(username).then(function (data) {\n history.push(\"/\");\n refreshUserData().then(function (data) {\n return dispatchUserData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Delete user\")))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\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 if (updatedUsername == \"\" && admin == has_admin) {\n noChangeEvent();\n return;\n } else if (updatedUsername != \"\") {\n if (updatedUsername.length > 2 && /[!@#$%^&*(),.?\":{}|<>]/g.test(updatedUsername) == false) {\n editUser(username, updatedUsername != \"\" ? updatedUsername : username, admin).then(function (data) {\n history.push(\"/\");\n refreshUserData().then(function (data) {\n return dispatchUserData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {});\n } else {\n setUpdatedUsername(\"\");\n failRegexEvent();\n }\n } else {\n editUser(username, username, admin).then(function (data) {\n history.push(\"/\");\n refreshUserData().then(function (data) {\n return dispatchUserData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {});\n }\n }\n }, \"Apply\")))))));\n};\n\nEditUser.propTypes = {\n location: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n state: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n username: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().string),\n has_admin: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().bool)\n })\n }),\n history: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func)\n }),\n editUser: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n deleteUser: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n noChangeEvent: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n refreshUserData: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EditUser);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/EditUser/EditUser.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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\");\n/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_2__);\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\");\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\nvar EditUser = function EditUser(props) {\n var limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.limit;\n });\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\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 var editUser = props.editUser,\n deleteUser = props.deleteUser,\n failRegexEvent = props.failRegexEvent,\n noChangeEvent = props.noChangeEvent,\n updateUsers = props.updateUsers,\n history = props.history;\n\n if (props.location.state == undefined) {\n props.history.push(\"/\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n\n var _props$location$state = props.location.state,\n username = _props$location$state.username,\n has_admin = _props$location$state.has_admin;\n\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\"),\n _useState2 = _slicedToArray(_useState, 2),\n updatedUsername = _useState2[0],\n setUpdatedUsername = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(has_admin),\n _useState4 = _slicedToArray(_useState3, 2),\n admin = _useState4[0],\n setAdmin = _useState4[1];\n\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, \"Editing user \", username)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"form\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"textarea\", {\n className: \"form-control\",\n id: \"exampleFormControlTextarea1\",\n rows: \"3\",\n placeholder: \"updated username\",\n onBlur: function onBlur(e) {\n setUpdatedUsername(e.target.value);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"input\", {\n className: \"form-check-input\",\n checked: admin,\n type: \"checkbox\",\n id: \"admin-check\",\n onChange: function onChange(e) {\n return setAdmin(!admin);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", null, \" \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"label\", {\n className: \"form-check-label\"\n }, \"Admin\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"delete-user\",\n className: \"btn btn-danger btn-sm\",\n onClick: function onClick() {\n deleteUser(username).then(function (data) {\n updateUsers(0, limit).then(function (data) {\n return dispatchPageChange(data, 0);\n }).then(function () {\n return history.push(\"/\");\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Delete user\")))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\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 if (updatedUsername == \"\" && admin == has_admin) {\n noChangeEvent();\n return;\n } else if (updatedUsername != \"\") {\n if (updatedUsername.length > 2 && /[!@#$%^&*(),.?\":{}|<>]/g.test(updatedUsername) == false) {\n editUser(username, updatedUsername != \"\" ? updatedUsername : username, admin).then(function (data) {\n updateUsers(0, limit).then(function (data) {\n return dispatchPageChange(data, 0);\n }).then(function () {\n return history.push(\"/\");\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {});\n } else {\n setUpdatedUsername(\"\");\n failRegexEvent();\n }\n } else {\n editUser(username, username, admin).then(function (data) {\n updateUsers(0, limit).then(function (data) {\n return dispatchPageChange(data, 0);\n }).then(function () {\n return history.push(\"/\");\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n })[\"catch\"](function (err) {});\n }\n }\n }, \"Apply\")))))));\n};\n\nEditUser.propTypes = {\n location: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n state: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n username: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().string),\n has_admin: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().bool)\n })\n }),\n history: prop_types__WEBPACK_IMPORTED_MODULE_2___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func)\n }),\n editUser: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n deleteUser: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n failRegexEvent: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n noChangeEvent: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func),\n updateUsers: (prop_types__WEBPACK_IMPORTED_MODULE_2___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EditUser);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/EditUser/EditUser.jsx?"); /***/ }), @@ -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 */ \"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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.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 _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\n/* harmony import */ var _Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Multiselect/Multiselect */ \"./src/components/Multiselect/Multiselect.jsx\");\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\nvar GroupEdit = function GroupEdit(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]),\n _useState2 = _slicedToArray(_useState, 2),\n selected = _useState2[0],\n setSelected = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),\n _useState4 = _slicedToArray(_useState3, 2),\n changed = _useState4[0],\n setChanged = _useState4[1],\n _useState5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState6 = _slicedToArray(_useState5, 2),\n added = _useState6[0],\n setAdded = _useState6[1],\n _useState7 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState8 = _slicedToArray(_useState7, 2),\n removed = _useState8[0],\n setRemoved = _useState8[1];\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchGroupsData = function dispatchGroupsData(data) {\n dispatch({\n type: \"GROUPS_DATA\",\n value: data\n });\n };\n\n var addToGroup = props.addToGroup,\n removeFromGroup = props.removeFromGroup,\n deleteGroup = props.deleteGroup,\n refreshGroupsData = props.refreshGroupsData,\n history = props.history,\n location = props.location;\n\n if (!location.state) {\n history.push(\"/groups\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n\n var _location$state = location.state,\n group_data = _location$state.group_data,\n user_data = _location$state.user_data,\n callback = _location$state.callback;\n if (!(group_data && user_data)) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n return /*#__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(\"h3\", null, \"Editing Group \", group_data.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"alert alert-info\"\n }, \"Select group members\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_5__.default, {\n options: user_data.map(function (e) {\n return e.name;\n }),\n value: group_data.users,\n onChange: function onChange(selection, options) {\n setSelected(selection);\n setChanged(true);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__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_6__.Link, {\n to: \"/groups\"\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 // check for changes\n if (!changed) {\n history.push(\"/groups\");\n return;\n }\n\n var new_users = selected.filter(function (e) {\n return !group_data.users.includes(e);\n });\n var removed_users = group_data.users.filter(function (e) {\n return !selected.includes(e);\n });\n setAdded(new_users);\n setRemoved(removed_users);\n var promiseQueue = [];\n if (new_users.length > 0) promiseQueue.push(addToGroup(new_users, group_data.name));\n if (removed_users.length > 0) promiseQueue.push(removeFromGroup(removed_users, group_data.name));\n Promise.all(promiseQueue).then(function (e) {\n return callback();\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n history.push(\"/groups\");\n }\n }, \"Apply\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"delete-group\",\n className: \"btn btn-danger\",\n style: {\n \"float\": \"right\"\n },\n onClick: function onClick() {\n var groupName = group_data.name;\n deleteGroup(groupName).then(refreshGroupsData().then(function (data) {\n return dispatchGroupsData(data);\n })).then(history.push(\"/groups\"))[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Delete Group\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null))));\n};\n\nGroupEdit.propTypes = {\n location: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n state: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n group_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n })\n }),\n history: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n }),\n addToGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n removeFromGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n deleteGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n refreshGroupsData: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GroupEdit);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/GroupEdit/GroupEdit.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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.esm.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.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 _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\n/* harmony import */ var _Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Multiselect/Multiselect */ \"./src/components/Multiselect/Multiselect.jsx\");\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\nvar GroupEdit = function GroupEdit(props) {\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]),\n _useState2 = _slicedToArray(_useState, 2),\n selected = _useState2[0],\n setSelected = _useState2[1],\n _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),\n _useState4 = _slicedToArray(_useState3, 2),\n changed = _useState4[0],\n setChanged = _useState4[1],\n _useState5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState6 = _slicedToArray(_useState5, 2),\n added = _useState6[0],\n setAdded = _useState6[1],\n _useState7 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(undefined),\n _useState8 = _slicedToArray(_useState7, 2),\n removed = _useState8[0],\n setRemoved = _useState8[1],\n limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.limit;\n });\n\n var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n\n var dispatchPageUpdate = function dispatchPageUpdate(data, page) {\n dispatch({\n type: \"GROUPS_PAGE\",\n value: {\n data: data,\n page: page\n }\n });\n };\n\n var addToGroup = props.addToGroup,\n removeFromGroup = props.removeFromGroup,\n deleteGroup = props.deleteGroup,\n updateGroups = props.updateGroups,\n history = props.history,\n location = props.location;\n\n if (!location.state) {\n history.push(\"/groups\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n\n var _location$state = location.state,\n group_data = _location$state.group_data,\n user_data = _location$state.user_data,\n callback = _location$state.callback;\n if (!(group_data && user_data)) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n return /*#__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(\"h3\", null, \"Editing Group \", group_data.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"alert alert-info\"\n }, \"Select group members\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_Multiselect_Multiselect__WEBPACK_IMPORTED_MODULE_5__.default, {\n options: user_data.map(function (e) {\n return e.name;\n }),\n value: group_data.users,\n onChange: function onChange(selection, options) {\n setSelected(selection);\n setChanged(true);\n }\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__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_6__.Link, {\n to: \"/groups\"\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 // check for changes\n if (!changed) {\n history.push(\"/groups\");\n return;\n }\n\n var new_users = selected.filter(function (e) {\n return !group_data.users.includes(e);\n });\n var removed_users = group_data.users.filter(function (e) {\n return !selected.includes(e);\n });\n setAdded(new_users);\n setRemoved(removed_users);\n var promiseQueue = [];\n if (new_users.length > 0) promiseQueue.push(addToGroup(new_users, group_data.name));\n if (removed_users.length > 0) promiseQueue.push(removeFromGroup(removed_users, group_data.name));\n Promise.all(promiseQueue).then(function (e) {\n updateGroups(0, limit).then(function (data) {\n return dispatchPageUpdate(data, 0);\n }).then(function () {\n return history.push(\"/groups\");\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Apply\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n id: \"delete-group\",\n className: \"btn btn-danger\",\n style: {\n \"float\": \"right\"\n },\n onClick: function onClick() {\n var groupName = group_data.name;\n deleteGroup(groupName).then(function (e) {\n updateGroups(0, limit).then(function (data) {\n return dispatchPageUpdate(data, 0);\n }).then(function () {\n return history.push(\"/groups\");\n });\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }, \"Delete Group\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null))));\n};\n\nGroupEdit.propTypes = {\n location: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n state: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n group_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().object),\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n callback: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n })\n }),\n history: prop_types__WEBPACK_IMPORTED_MODULE_3___default().shape({\n push: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n }),\n addToGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n removeFromGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n deleteGroup: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n updateGroups: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GroupEdit);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/GroupEdit/GroupEdit.jsx?"); /***/ }), @@ -155,7 +155,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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.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__);\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _util_jhapiUtil__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../util/jhapiUtil */ \"./src/util/jhapiUtil.js\");\n\n\n\n\n\n\n\nvar Groups = function Groups(props) {\n var user_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.user_data;\n }),\n groups_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.groups_data;\n }),\n dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();\n var refreshGroupsData = props.refreshGroupsData,\n refreshUserData = props.refreshUserData,\n history = props.history;\n\n if (!groups_data || !user_data) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n }\n\n var dispatchGroupsData = function dispatchGroupsData(data) {\n dispatch({\n type: \"GROUPS_DATA\",\n value: data\n });\n };\n\n var dispatchUserData = function dispatchUserData(data) {\n dispatch({\n type: \"USER_DATA\",\n value: data\n });\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: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"col-md-12 col-lg-10 col-lg-offset-1\"\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, \"Groups\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, groups_data.length > 0 ? groups_data.map(function (e, i) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n key: \"group-edit\" + i,\n className: \"group-edit-link\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"h4\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_5__.Link, {\n to: {\n pathname: \"/group-edit\",\n state: {\n group_data: e,\n user_data: user_data,\n callback: function callback() {\n refreshGroupsData().then(function (data) {\n return dispatchGroupsData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n refreshUserData().then(function (data) {\n return dispatchUserData(data);\n })[\"catch\"](function (err) {\n return console.log(err);\n });\n }\n }\n }\n }, e.name)));\n }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"h4\", null, \"no groups created...\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-light adjacent-span-spacing\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_5__.Link, {\n to: \"/\"\n }, \"Back\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary adjacent-span-spacing\",\n onClick: function onClick() {\n history.push(\"/create-group\");\n }\n }, \"New Group\"))))));\n};\n\nGroups.propTypes = {\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n groups_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n refreshUserData: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n refreshGroupsData: (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/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Groups);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/Groups/Groups.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 react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var recompose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recompose */ \"./node_modules/recompose/dist/Recompose.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__);\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _PaginationFooter_PaginationFooter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../PaginationFooter/PaginationFooter */ \"./src/components/PaginationFooter/PaginationFooter.jsx\");\n\n\n\n\n\n\n\nvar Groups = function Groups(props) {\n var user_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.user_data;\n }),\n groups_data = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.groups_data;\n }),\n groups_page = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.groups_page;\n }),\n user_page = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.user_page;\n }),\n limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(function (state) {\n return state.limit;\n }),\n dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)(),\n page = parseInt(new URLSearchParams(props.location.search).get(\"page\"));\n page = isNaN(page) ? 0 : page;\n var slice = [page * limit, limit];\n var updateGroups = props.updateGroups,\n history = props.history;\n\n if (!groups_data || !user_data) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null);\n }\n\n var dispatchPageChange = function dispatchPageChange(data, page) {\n dispatch({\n type: \"GROUPS_PAGE\",\n value: {\n data: data,\n page: page\n }\n });\n };\n\n if (groups_page != page) {\n updateGroups.apply(void 0, slice).then(function (data) {\n dispatchPageChange(data, page);\n });\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: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"col-md-12 col-lg-10 col-lg-offset-1\"\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, \"Groups\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-body\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"ul\", {\n className: \"list-group\"\n }, groups_data.length > 0 ? groups_data.map(function (e, i) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", {\n className: \"list-group-item\",\n key: \"group-item\" + i\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n className: \"badge badge-pill badge-success\"\n }, e.users.length + \" users\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_5__.Link, {\n to: {\n pathname: \"/group-edit\",\n state: {\n group_data: e,\n user_data: user_data\n }\n }\n }, e.name));\n }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"h4\", null, \"no groups created...\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(_PaginationFooter_PaginationFooter__WEBPACK_IMPORTED_MODULE_4__.default, {\n endpoint: \"/groups\",\n page: page,\n limit: limit,\n numOffset: slice[0],\n numElements: groups_data.length\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"panel-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-light adjacent-span-spacing\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_5__.Link, {\n to: \"/\"\n }, \"Back\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-primary adjacent-span-spacing\",\n onClick: function onClick() {\n history.push(\"/create-group\");\n }\n }, \"New Group\"))))));\n};\n\nGroups.propTypes = {\n user_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n groups_data: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().array),\n updateUsers: (prop_types__WEBPACK_IMPORTED_MODULE_3___default().func),\n updateGroups: (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/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Groups);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/Groups/Groups.jsx?"); /***/ }), @@ -174,6 +174,21 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./src/components/PaginationFooter/PaginationFooter.jsx": +/*!**************************************************************!*\ + !*** ./src/components/PaginationFooter/PaginationFooter.jsx ***! + \**************************************************************/ +/*! namespace exports */ +/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ +/*! other exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_exports__, __webpack_require__.r, __webpack_require__.d, __webpack_require__.* */ +/***/ ((__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 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 _pagination_footer_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pagination-footer.css */ \"./src/components/PaginationFooter/pagination-footer.css\");\n\n\n\n\n\nvar PaginationFooter = function PaginationFooter(props) {\n var endpoint = props.endpoint,\n page = props.page,\n limit = props.limit,\n numOffset = props.numOffset,\n numElements = props.numElements;\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n className: \"pagination-footer\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Displaying \", numOffset, \"-\", numOffset + numElements, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null), page >= 1 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-sm btn-light spaced\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_3__.Link, {\n to: \"\".concat(endpoint, \"?page=\").concat(page - 1)\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n className: \"active-pagination\"\n }, \"Previous\"))) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-sm btn-light spaced\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n className: \"inactive-pagination\"\n }, \"Previous\")), numElements >= limit ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-sm btn-light spaced\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_3__.Link, {\n to: \"\".concat(endpoint, \"?page=\").concat(page + 1)\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n className: \"active-pagination\"\n }, \"Next\"))) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", {\n className: \"btn btn-sm btn-light spaced\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n className: \"inactive-pagination\"\n }, \"Next\"))));\n};\n\nPaginationFooter.propTypes = {\n endpoint: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().string),\n page: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().number),\n limit: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().number),\n numOffset: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().number),\n numElements: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().number)\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PaginationFooter);\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/PaginationFooter/PaginationFooter.jsx?"); + +/***/ }), + /***/ "./src/components/ServerDashboard/ServerDashboard.jsx": /*!************************************************************!*\ !*** ./src/components/ServerDashboard/ServerDashboard.jsx ***! @@ -185,7 +200,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 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?"); +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_9__ = __webpack_require__(/*! react-bootstrap */ \"./node_modules/react-bootstrap/esm/Button.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_8__ = __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_10__ = __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\");\n/* harmony import */ var _PaginationFooter_PaginationFooter__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../PaginationFooter/PaginationFooter */ \"./src/components/PaginationFooter/PaginationFooter.jsx\");\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\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 user_page = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.user_page;\n }),\n limit = (0,react_redux__WEBPACK_IMPORTED_MODULE_2__.useSelector)(function (state) {\n return state.limit;\n }),\n page = parseInt(new URLSearchParams(props.location.search).get(\"page\"));\n console.log(user_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 dispatchPageUpdate = function dispatchPageUpdate(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 dispatchPageUpdate(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_8__.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_9__.default, {\n variant: \"light\",\n className: \"add-users-button\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_8__.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_9__.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 dispatchPageUpdate(data, page);\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_9__.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 dispatchPageUpdate(data, page);\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_9__.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 dispatchPageUpdate(data, page);\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 dispatchPageUpdate(data, page);\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(_PaginationFooter_PaginationFooter__WEBPACK_IMPORTED_MODULE_7__.default, {\n endpoint: \"/\",\n page: page,\n limit: limit,\n numOffset: slice[0],\n numElements: user_data.length\n }), /*#__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_10__.FaSort, null) : direction == \"asc\" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_10__.FaSortDown, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_icons_fa__WEBPACK_IMPORTED_MODULE_10__.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 +245,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(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?"); +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\").then(function (data) {\n return data.json();\n });\n },\n updateGroups: function updateGroups(offset, limit) {\n return (0,_jhapiUtil__WEBPACK_IMPORTED_MODULE_1__.jhapiRequest)(\"/groups?offset=\".concat(offset, \"&limit=\").concat(limit), \"GET\").then(function (data) {\n return data.json();\n });\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?"); /***/ }), @@ -279,6 +294,21 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./node_modules/css-loader/dist/cjs.js!./src/components/PaginationFooter/pagination-footer.css": +/*!*****************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./src/components/PaginationFooter/pagination-footer.css ***! + \*****************************************************************************************************/ +/*! namespace exports */ +/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ +/*! other exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_exports__, __webpack_require__.r, module.id, __webpack_require__.d, __webpack_require__.*, module */ +/***/ ((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, \".pagination-footer * button {\\n margin-right: 10px;\\n}\\n\\n.pagination-footer * .inactive-pagination {\\n color: gray;\\n cursor: not-allowed;\\n}\\n\\n.pagination-footer * button.spaced {\\n color: var(--blue);\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/PaginationFooter/pagination-footer.css?./node_modules/css-loader/dist/cjs.js"); + +/***/ }), + /***/ "./node_modules/css-loader/dist/cjs.js!./src/components/ServerDashboard/server-dashboard.css": /*!***************************************************************************************************!*\ !*** ./node_modules/css-loader/dist/cjs.js!./src/components/ServerDashboard/server-dashboard.css ***! @@ -305,7 +335,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// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root {\\n --red: #d7191e;\\n --orange: #f1ad4e;\\n --blue: #2e7ab6;\\n --white: #ffffff;\\n --gray: #f7f7f;\\n}\\n\\n/* Color Classes */\\n.red {\\n background-color: var(--red);\\n}\\n.orange {\\n background-color: var(--orange);\\n}\\n.blue {\\n background-color: var(--blue);\\n}\\n.white {\\n background-color: var(--white);\\n}\\n\\n/* Resets */\\n\\n.resets .modal {\\n display: block;\\n visibility: visible;\\n z-index: 2000;\\n}\\n\\n/* Global Util Classes */\\n.adjacent-span-spacing {\\n margin-right: 5px;\\n margin-left: 5px;\\n}\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/style/root.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// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root {\\n --red: #d7191e;\\n --orange: #f1ad4e;\\n --blue: #2e7ab6;\\n --white: #ffffff;\\n --gray: #f7f7f7;\\n}\\n\\n/* Color Classes */\\n.red {\\n background-color: var(--red);\\n}\\n.orange {\\n background-color: var(--orange);\\n}\\n.blue {\\n background-color: var(--blue);\\n}\\n.white {\\n background-color: var(--white);\\n}\\n\\n/* Resets */\\n\\n.resets .modal {\\n display: block;\\n visibility: visible;\\n z-index: 2000;\\n}\\n\\n/* Global Util Classes */\\n.adjacent-span-spacing {\\n margin-right: 5px;\\n margin-left: 5px;\\n}\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/style/root.css?./node_modules/css-loader/dist/cjs.js"); /***/ }), @@ -3121,6 +3151,21 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./src/components/PaginationFooter/pagination-footer.css": +/*!***************************************************************!*\ + !*** ./src/components/PaginationFooter/pagination-footer.css ***! + \***************************************************************/ +/*! namespace exports */ +/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ +/*! other exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_exports__, __webpack_require__.r, module, __webpack_require__.d, __webpack_require__.* */ +/***/ ((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_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !!../../../node_modules/css-loader/dist/cjs.js!./pagination-footer.css */ \"./node_modules/css-loader/dist/cjs.js!./src/components/PaginationFooter/pagination-footer.css\");\n\n \n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default, options);\n\n\nif (true) {\n if (!_node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default.locals || module.hot.invalidate) {\n var isEqualLocals = function isEqualLocals(a, b, isNamedExport) {\n if (!a && b || a && !b) {\n return false;\n }\n\n var p;\n\n for (p in a) {\n if (isNamedExport && p === 'default') {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (a[p] !== b[p]) {\n return false;\n }\n }\n\n for (p in b) {\n if (isNamedExport && p === 'default') {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (!a[p]) {\n return false;\n }\n }\n\n return true;\n};\n var oldLocals = _node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default.locals;\n\n module.hot.accept(\n /*! !!../../../node_modules/css-loader/dist/cjs.js!./pagination-footer.css */ \"./node_modules/css-loader/dist/cjs.js!./src/components/PaginationFooter/pagination-footer.css\",\n __WEBPACK_OUTDATED_DEPENDENCIES__ => { /* harmony import */ _node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !!../../../node_modules/css-loader/dist/cjs.js!./pagination-footer.css */ \"./node_modules/css-loader/dist/cjs.js!./src/components/PaginationFooter/pagination-footer.css\");\n(function () {\n if (!isEqualLocals(oldLocals, _node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default.locals, undefined)) {\n module.hot.invalidate();\n\n return;\n }\n\n oldLocals = _node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default.locals;\n\n update(_node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default);\n })(__WEBPACK_OUTDATED_DEPENDENCIES__); }\n )\n }\n\n module.hot.dispose(function() {\n update();\n });\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_pagination_footer_css__WEBPACK_IMPORTED_MODULE_1__.default.locals || {});\n\n//# sourceURL=webpack://jupyterhub-admin-react/./src/components/PaginationFooter/pagination-footer.css?"); + +/***/ }), + /***/ "./src/components/ServerDashboard/server-dashboard.css": /*!*************************************************************!*\ !*** ./src/components/ServerDashboard/server-dashboard.css ***! @@ -3321,7 +3366,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /******/ /******/ /* webpack/runtime/getFullHash */ /******/ (() => { -/******/ __webpack_require__.h = () => "a33ad3442e1d265c1688" +/******/ __webpack_require__.h = () => "cf1a004691a499583483" /******/ })(); /******/ /******/ /* webpack/runtime/global */