mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-11 12:03:00 +00:00
Add UI error dialogues to api requests
This commit is contained in:
@@ -29,7 +29,16 @@ const AddUser = (props) => {
|
|||||||
{errorAlert != null ? (
|
{errorAlert != null ? (
|
||||||
<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="alert alert-danger">{errorAlert}</div>
|
<div className="alert alert-danger">
|
||||||
|
{errorAlert}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="close"
|
||||||
|
onClick={() => setErrorAlert(null)}
|
||||||
|
>
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -94,7 +103,7 @@ const AddUser = (props) => {
|
|||||||
.then(() => history.push("/"))
|
.then(() => history.push("/"))
|
||||||
.catch((err) => console.log(err))
|
.catch((err) => console.log(err))
|
||||||
: setErrorAlert(
|
: setErrorAlert(
|
||||||
`[${data.status}] Failed to create user. ${
|
`Failed to create user. ${
|
||||||
data.status == 409 ? "User already exists." : ""
|
data.status == 409 ? "User already exists." : ""
|
||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
|
@@ -28,7 +28,16 @@ const CreateGroup = (props) => {
|
|||||||
{errorAlert != null ? (
|
{errorAlert != null ? (
|
||||||
<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="alert alert-danger">{errorAlert}</div>
|
<div className="alert alert-danger">
|
||||||
|
{errorAlert}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="close"
|
||||||
|
onClick={() => setErrorAlert(null)}
|
||||||
|
>
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -69,16 +78,18 @@ const CreateGroup = (props) => {
|
|||||||
? updateGroups(0, limit)
|
? updateGroups(0, limit)
|
||||||
.then((data) => dispatchPageUpdate(data, 0))
|
.then((data) => dispatchPageUpdate(data, 0))
|
||||||
.then(() => history.push("/groups"))
|
.then(() => history.push("/groups"))
|
||||||
.catch((err) => console.log(err))
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not update groups list.`)
|
||||||
|
)
|
||||||
: setErrorAlert(
|
: setErrorAlert(
|
||||||
`[${data.status}] Failed to create group. ${
|
`Failed to create group. ${
|
||||||
data.status == 409
|
data.status == 409
|
||||||
? "Group already exists."
|
? "Group already exists."
|
||||||
: ""
|
: ""
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => setErrorAlert(`Could not create group.`));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Create
|
Create
|
||||||
|
@@ -44,7 +44,16 @@ const EditUser = (props) => {
|
|||||||
{errorAlert != null ? (
|
{errorAlert != null ? (
|
||||||
<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="alert alert-danger">{errorAlert}</div>
|
<div className="alert alert-danger">
|
||||||
|
{errorAlert}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="close"
|
||||||
|
onClick={() => setErrorAlert(null)}
|
||||||
|
>
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -89,12 +98,16 @@ const EditUser = (props) => {
|
|||||||
? updateUsers(0, limit)
|
? updateUsers(0, limit)
|
||||||
.then((data) => dispatchPageChange(data, 0))
|
.then((data) => dispatchPageChange(data, 0))
|
||||||
.then(() => history.push("/"))
|
.then(() => history.push("/"))
|
||||||
.catch((err) => console.log(err))
|
.catch((err) =>
|
||||||
: setErrorAlert(
|
setErrorAlert(
|
||||||
`[${data.status}] Failed to edit user.`
|
`Could not update users list.`
|
||||||
);
|
)
|
||||||
|
)
|
||||||
|
: setErrorAlert(`Failed to edit user.`);
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => {
|
||||||
|
setErrorAlert(`Failed to edit user.`);
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Delete user
|
Delete user
|
||||||
@@ -129,17 +142,20 @@ const EditUser = (props) => {
|
|||||||
? updateUsers(0, limit)
|
? updateUsers(0, limit)
|
||||||
.then((data) => dispatchPageChange(data, 0))
|
.then((data) => dispatchPageChange(data, 0))
|
||||||
.then(() => history.push("/"))
|
.then(() => history.push("/"))
|
||||||
.catch((err) => console.log(err))
|
.catch((err) =>
|
||||||
: setErrorAlert(
|
setErrorAlert(
|
||||||
`[${data.status}] Failed to edit user.`
|
`Could not update users list.`
|
||||||
);
|
)
|
||||||
|
)
|
||||||
|
: setErrorAlert(`Failed to edit user.`);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
setErrorAlert(`Failed to edit user.`);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setUpdatedUsername("");
|
setErrorAlert(
|
||||||
failRegexEvent();
|
`Failed to edit user. Make sure the username does not contain special characters.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
editUser(username, username, admin)
|
editUser(username, username, admin)
|
||||||
@@ -148,13 +164,13 @@ const EditUser = (props) => {
|
|||||||
? updateUsers(0, limit)
|
? updateUsers(0, limit)
|
||||||
.then((data) => dispatchPageChange(data, 0))
|
.then((data) => dispatchPageChange(data, 0))
|
||||||
.then(() => history.push("/"))
|
.then(() => history.push("/"))
|
||||||
.catch((err) => console.log(err))
|
.catch((err) =>
|
||||||
: setErrorAlert(
|
setErrorAlert(`Could not update users list.`)
|
||||||
`[${data.status}] Failed to edit user.`
|
)
|
||||||
);
|
: setErrorAlert(`Failed to edit user.`);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
setErrorAlert(`Failed to edit user.`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@@ -7,6 +7,7 @@ import GroupSelect from "../GroupSelect/GroupSelect";
|
|||||||
const GroupEdit = (props) => {
|
const GroupEdit = (props) => {
|
||||||
var [selected, setSelected] = useState([]),
|
var [selected, setSelected] = useState([]),
|
||||||
[changed, setChanged] = useState(false),
|
[changed, setChanged] = useState(false),
|
||||||
|
[errorAlert, setErrorAlert] = useState(null),
|
||||||
limit = useSelector((state) => state.limit);
|
limit = useSelector((state) => state.limit);
|
||||||
|
|
||||||
var dispatch = useDispatch();
|
var dispatch = useDispatch();
|
||||||
@@ -42,6 +43,24 @@ const GroupEdit = (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}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="close"
|
||||||
|
onClick={() => setErrorAlert(null)}
|
||||||
|
>
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</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">
|
||||||
<h3>Editing Group {group_data.name}</h3>
|
<h3>Editing Group {group_data.name}</h3>
|
||||||
@@ -89,12 +108,13 @@ const GroupEdit = (props) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Promise.all(promiseQueue)
|
Promise.all(promiseQueue)
|
||||||
|
// TODO add error if res not ok
|
||||||
.then(() => {
|
.then(() => {
|
||||||
updateGroups(0, limit)
|
updateGroups(0, limit)
|
||||||
.then((data) => dispatchPageUpdate(data, 0))
|
.then((data) => dispatchPageUpdate(data, 0))
|
||||||
.then(() => history.push("/groups"));
|
.then(() => history.push("/groups"));
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => setErrorAlert(`Could not edit group.`));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Apply
|
Apply
|
||||||
@@ -106,12 +126,13 @@ const GroupEdit = (props) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
var groupName = group_data.name;
|
var groupName = group_data.name;
|
||||||
deleteGroup(groupName)
|
deleteGroup(groupName)
|
||||||
|
// TODO add error if res not ok
|
||||||
.then(() => {
|
.then(() => {
|
||||||
updateGroups(0, limit)
|
updateGroups(0, limit)
|
||||||
.then((data) => dispatchPageUpdate(data, 0))
|
.then((data) => dispatchPageUpdate(data, 0))
|
||||||
.then(() => history.push("/groups"));
|
.then(() => history.push("/groups"));
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => setErrorAlert(`Could not delete group.`));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Delete Group
|
Delete Group
|
||||||
|
@@ -27,6 +27,7 @@ const ServerDashboard = (props) => {
|
|||||||
runningAsc = (e) => e.sort((a) => (a.server == null ? -1 : 1)),
|
runningAsc = (e) => e.sort((a) => (a.server == null ? -1 : 1)),
|
||||||
runningDesc = (e) => e.sort((a) => (a.server == null ? 1 : -1));
|
runningDesc = (e) => e.sort((a) => (a.server == null ? 1 : -1));
|
||||||
|
|
||||||
|
var [errorAlert, setErrorAlert] = useState(null);
|
||||||
var [sortMethod, setSortMethod] = useState(null);
|
var [sortMethod, setSortMethod] = useState(null);
|
||||||
|
|
||||||
var user_data = useSelector((state) => state.user_data),
|
var user_data = useSelector((state) => state.user_data),
|
||||||
@@ -73,6 +74,24 @@ const ServerDashboard = (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}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="close"
|
||||||
|
onClick={() => setErrorAlert(null)}
|
||||||
|
>
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
<div className="manage-groups" style={{ float: "right", margin: "20px" }}>
|
<div className="manage-groups" style={{ float: "right", margin: "20px" }}>
|
||||||
<Link to="/groups">{"> Manage Groups"}</Link>
|
<Link to="/groups">{"> Manage Groups"}</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,15 +146,32 @@ const ServerDashboard = (props) => {
|
|||||||
className="start-all"
|
className="start-all"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Promise.all(startAll(user_data.map((e) => e.name)))
|
Promise.all(startAll(user_data.map((e) => e.name)))
|
||||||
|
.then((res) => {
|
||||||
|
let failedServers = res.filter((e) => !e.ok);
|
||||||
|
if (failedServers.length > 0) {
|
||||||
|
setErrorAlert(
|
||||||
|
`Could not start ${failedServers.length} ${
|
||||||
|
failedServers.length > 1 ? "servers" : "server"
|
||||||
|
}. ${
|
||||||
|
failedServers.length > 1 ? "Are they " : "Is it "
|
||||||
|
} already running?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
updateUsers(...slice)
|
updateUsers(...slice)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
dispatchPageUpdate(data, page);
|
dispatchPageUpdate(data, page);
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not update users list.`)
|
||||||
|
);
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not start servers.`)
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Start All
|
Start All
|
||||||
@@ -147,15 +183,32 @@ const ServerDashboard = (props) => {
|
|||||||
className="stop-all"
|
className="stop-all"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Promise.all(stopAll(user_data.map((e) => e.name)))
|
Promise.all(stopAll(user_data.map((e) => e.name)))
|
||||||
|
.then((res) => {
|
||||||
|
let failedServers = res.filter((e) => !e.ok);
|
||||||
|
if (failedServers.length > 0) {
|
||||||
|
setErrorAlert(
|
||||||
|
`Could not stop ${failedServers.length} ${
|
||||||
|
failedServers.length > 1 ? "servers" : "server"
|
||||||
|
}. ${
|
||||||
|
failedServers.length > 1 ? "Are they " : "Is it "
|
||||||
|
} already stopped?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
updateUsers(...slice)
|
updateUsers(...slice)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
dispatchPageUpdate(data, page);
|
dispatchPageUpdate(data, page);
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not update users list.`)
|
||||||
|
);
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not stop all servers.`)
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Stop All
|
Stop All
|
||||||
@@ -187,12 +240,22 @@ const ServerDashboard = (props) => {
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
stopServer(e.name)
|
stopServer(e.name)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
updateUsers(...slice).then((data) => {
|
if (res.ok) return res;
|
||||||
|
throw new Error(res.status);
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
updateUsers(...slice)
|
||||||
|
.then((data) => {
|
||||||
dispatchPageUpdate(data, page);
|
dispatchPageUpdate(data, page);
|
||||||
});
|
})
|
||||||
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not update users list.`)
|
||||||
|
);
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err))
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not stop server.`)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Stop Server
|
Stop Server
|
||||||
@@ -204,12 +267,22 @@ const ServerDashboard = (props) => {
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
startServer(e.name)
|
startServer(e.name)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
updateUsers(...slice).then((data) => {
|
if (res.ok) return res;
|
||||||
|
throw new Error(res.status);
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
updateUsers(...slice)
|
||||||
|
.then((data) => {
|
||||||
dispatchPageUpdate(data, page);
|
dispatchPageUpdate(data, page);
|
||||||
});
|
})
|
||||||
|
.catch((err) =>
|
||||||
|
setErrorAlert(`Could not update users list.`)
|
||||||
|
);
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err))
|
.catch((err) => {
|
||||||
|
setErrorAlert(`Could not start server.`);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Start Server
|
Start Server
|
||||||
|
@@ -7,9 +7,10 @@ const withAPI = withProps(() => ({
|
|||||||
data.json()
|
data.json()
|
||||||
),
|
),
|
||||||
updateGroups: (offset, limit) =>
|
updateGroups: (offset, limit) =>
|
||||||
jhapiRequest(`/groups?offset=${offset}&limit=${limit}`, "GET").then(
|
jhapiRequest(
|
||||||
(data) => data.json()
|
`/groups?offset=${offset}&limit=${limit}`,
|
||||||
),
|
"GET"
|
||||||
|
).then((data) => data.json()),
|
||||||
shutdownHub: () => jhapiRequest("/shutdown", "POST"),
|
shutdownHub: () => jhapiRequest("/shutdown", "POST"),
|
||||||
startServer: (name) => jhapiRequest("/users/" + name + "/server", "POST"),
|
startServer: (name) => jhapiRequest("/users/" + name + "/server", "POST"),
|
||||||
stopServer: (name) => jhapiRequest("/users/" + name + "/server", "DELETE"),
|
stopServer: (name) => jhapiRequest("/users/" + name + "/server", "DELETE"),
|
||||||
@@ -36,13 +37,8 @@ const withAPI = withProps(() => ({
|
|||||||
jhapiRequest("/users/" + username, "GET")
|
jhapiRequest("/users/" + username, "GET")
|
||||||
.then((data) => data.status)
|
.then((data) => data.status)
|
||||||
.then((data) => (data > 200 ? false : true)),
|
.then((data) => (data > 200 ? false : true)),
|
||||||
failRegexEvent: () =>
|
failRegexEvent: () => {},
|
||||||
alert(
|
noChangeEvent: () => {},
|
||||||
"Cannot change username - either contains special characters or is too short."
|
|
||||||
),
|
|
||||||
noChangeEvent: () => {
|
|
||||||
returns;
|
|
||||||
},
|
|
||||||
refreshGroupsData: () =>
|
refreshGroupsData: () =>
|
||||||
jhapiRequest("/groups", "GET").then((data) => data.json()),
|
jhapiRequest("/groups", "GET").then((data) => data.json()),
|
||||||
refreshUserData: () =>
|
refreshUserData: () =>
|
||||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user