mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-10 11:33:01 +00:00
Fix CreateGroup state update, add info alerts
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
"version": "detect"
|
"version": "detect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": ["eslint-plugin-react", "prettier"],
|
"plugins": ["eslint-plugin-react", "prettier", "unused-imports"],
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"browser": true
|
"browser": true
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"semi": "off",
|
"semi": "off",
|
||||||
"quotes": "off",
|
"quotes": "off",
|
||||||
"prettier/prettier": "warn"
|
"prettier/prettier": "warn",
|
||||||
|
"no-unused-vars": "warn"
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
"babel-loader": "^8.2.1",
|
"babel-loader": "^8.2.1",
|
||||||
"bootstrap": "^4.5.3",
|
"bootstrap": "^4.5.3",
|
||||||
"css-loader": "^5.0.1",
|
"css-loader": "^5.0.1",
|
||||||
|
"eslint-plugin-unused-imports": "^1.1.1",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"history": "^5.0.0",
|
"history": "^5.0.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React, { Component, useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import { createStore } from "redux";
|
import { createStore } from "redux";
|
||||||
@@ -6,7 +6,7 @@ import { compose } from "recompose";
|
|||||||
import { initialState, reducers } from "./Store";
|
import { initialState, reducers } from "./Store";
|
||||||
import { jhapiRequest } from "./util/jhapiUtil";
|
import { jhapiRequest } from "./util/jhapiUtil";
|
||||||
import withAPI from "./util/withAPI";
|
import withAPI from "./util/withAPI";
|
||||||
import { HashRouter, Switch, Route, Link } from "react-router-dom";
|
import { HashRouter, Switch, Route } from "react-router-dom";
|
||||||
|
|
||||||
import ServerDashboard from "./components/ServerDashboard/ServerDashboard";
|
import ServerDashboard from "./components/ServerDashboard/ServerDashboard";
|
||||||
import Groups from "./components/Groups/Groups";
|
import Groups from "./components/Groups/Groups";
|
||||||
@@ -19,17 +19,21 @@ import "./style/root.css";
|
|||||||
|
|
||||||
const store = createStore(reducers, initialState);
|
const store = createStore(reducers, initialState);
|
||||||
|
|
||||||
const App = (props) => {
|
const App = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let { limit, user_page, groups_page } = initialState;
|
let { limit, user_page, groups_page } = initialState;
|
||||||
jhapiRequest(`/users?offset=${user_page * limit}&limit=${limit}`, "GET")
|
jhapiRequest(`/users?offset=${user_page * limit}&limit=${limit}`, "GET")
|
||||||
.then((data) => data.json())
|
.then((data) => data.json())
|
||||||
.then((data) => store.dispatch({ type: "USER_DATA", value: data }))
|
.then((data) =>
|
||||||
|
store.dispatch({ type: "USER_PAGE", value: { data: data, page: 0 } })
|
||||||
|
)
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
|
|
||||||
jhapiRequest(`/groups?offset=${groups_page * limit}&limit=${limit}`, "GET")
|
jhapiRequest(`/groups?offset=${groups_page * limit}&limit=${limit}`, "GET")
|
||||||
.then((data) => data.json())
|
.then((data) => data.json())
|
||||||
.then((data) => store.dispatch({ type: "GROUPS_DATA", value: data }))
|
.then((data) =>
|
||||||
|
store.dispatch({ type: "GROUPS_PAGE", value: { data: data, page: 0 } })
|
||||||
|
)
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -17,10 +17,6 @@ export const reducers = (state = initialState, action) => {
|
|||||||
user_data: action.value.data,
|
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
|
// Updates the client group model data and stores the page
|
||||||
case "GROUPS_PAGE":
|
case "GROUPS_PAGE":
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
@@ -28,10 +24,6 @@ export const reducers = (state = initialState, action) => {
|
|||||||
groups_data: action.value.data,
|
groups_data: action.value.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deprecated - doesn't store pagination values
|
|
||||||
case "GROUPS_DATA":
|
|
||||||
return Object.assign({}, state, { groups_data: action.value });
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import { jhapiRequest } from "../../util/jhapiUtil";
|
|||||||
const AddUser = (props) => {
|
const AddUser = (props) => {
|
||||||
var [users, setUsers] = useState([]),
|
var [users, setUsers] = useState([]),
|
||||||
[admin, setAdmin] = useState(false),
|
[admin, setAdmin] = useState(false),
|
||||||
|
[errorAlert, setErrorAlert] = useState(null),
|
||||||
limit = useSelector((state) => state.limit);
|
limit = useSelector((state) => state.limit);
|
||||||
|
|
||||||
var dispatch = useDispatch();
|
var dispatch = useDispatch();
|
||||||
@@ -27,6 +28,15 @@ const AddUser = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
|
{errorAlert != null ? (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||||
|
<div className="alert alert-danger">{errorAlert}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||||
<div className="panel panel-default">
|
<div className="panel panel-default">
|
||||||
@@ -82,11 +92,17 @@ const AddUser = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addUsers(filtered_users, admin)
|
addUsers(filtered_users, admin)
|
||||||
.then(() =>
|
.then((data) =>
|
||||||
updateUsers(0, limit)
|
data.status < 300
|
||||||
.then((data) => dispatchPageChange(data, 0))
|
? updateUsers(0, limit)
|
||||||
.then(() => history.push("/"))
|
.then((data) => dispatchPageChange(data, 0))
|
||||||
.catch((err) => console.log(err))
|
.then(() => history.push("/"))
|
||||||
|
.catch((err) => console.log(err))
|
||||||
|
: setErrorAlert(
|
||||||
|
`[${data.status}] Failed to create user. ${
|
||||||
|
data.status == 409 ? "User already exists." : ""
|
||||||
|
}`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
}}
|
}}
|
||||||
|
@@ -5,13 +5,14 @@ import PropTypes from "prop-types";
|
|||||||
|
|
||||||
const CreateGroup = (props) => {
|
const CreateGroup = (props) => {
|
||||||
var [groupName, setGroupName] = useState(""),
|
var [groupName, setGroupName] = useState(""),
|
||||||
|
[errorAlert, setErrorAlert] = useState(null),
|
||||||
limit = useSelector((state) => state.limit);
|
limit = useSelector((state) => state.limit);
|
||||||
|
|
||||||
var dispatch = useDispatch();
|
var dispatch = useDispatch();
|
||||||
|
|
||||||
var dispatchPageUpdate = (data, page) => {
|
var dispatchPageUpdate = (data, page) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "GROUPS_DATA",
|
type: "GROUPS_PAGE",
|
||||||
value: {
|
value: {
|
||||||
data: data,
|
data: data,
|
||||||
page: page,
|
page: page,
|
||||||
@@ -24,6 +25,15 @@ const CreateGroup = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
|
{errorAlert != null ? (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||||
|
<div className="alert alert-danger">{errorAlert}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||||
<div className="panel panel-default">
|
<div className="panel panel-default">
|
||||||
@@ -54,11 +64,19 @@ const CreateGroup = (props) => {
|
|||||||
className="btn btn-primary"
|
className="btn btn-primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
createGroup(groupName)
|
createGroup(groupName)
|
||||||
.then(
|
.then((data) =>
|
||||||
updateGroups(0, limit)
|
data.status < 300
|
||||||
.then((data) => dispatchPageUpdate(data, 0))
|
? updateGroups(0, limit)
|
||||||
.then(history.push("/groups"))
|
.then((data) => dispatchPageUpdate(data, 0))
|
||||||
.catch((err) => console.log(err))
|
.then((data) => history.push("/groups"))
|
||||||
|
.catch((err) => console.log(err))
|
||||||
|
: setErrorAlert(
|
||||||
|
`[${data.status}] Failed to create group. ${
|
||||||
|
data.status == 409
|
||||||
|
? "Group already exists."
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
}}
|
}}
|
||||||
|
@@ -3073,6 +3073,18 @@ eslint-plugin-react@^7.22.0:
|
|||||||
resolve "^1.18.1"
|
resolve "^1.18.1"
|
||||||
string.prototype.matchall "^4.0.2"
|
string.prototype.matchall "^4.0.2"
|
||||||
|
|
||||||
|
eslint-plugin-unused-imports@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-1.1.1.tgz#a5433f8b394461201129a246d8d92d9613e69597"
|
||||||
|
integrity sha512-EApvRx9Q3XQI96Tg7xPPqY6OuOy95wWMXAtc8RrwdIRk9bv8vkJKwOVoE4HeWJOQhHeHcI8lUbOqmup/PxjfOw==
|
||||||
|
dependencies:
|
||||||
|
eslint-rule-composer "^0.3.0"
|
||||||
|
|
||||||
|
eslint-rule-composer@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9"
|
||||||
|
integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==
|
||||||
|
|
||||||
eslint-scope@^5.1.1:
|
eslint-scope@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user