mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-13 13:03:01 +00:00
Make GroupEdit functional
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { compose, withProps } from "recompose";
|
import { compose, withProps } from "recompose";
|
||||||
import { jhapiRequest } from "../../util/jhapiUtil";
|
import { jhapiRequest } from "../../util/jhapiUtil";
|
||||||
import { GroupEdit } from "./GroupEdit.pre";
|
import GroupEdit from "./GroupEdit.pre";
|
||||||
|
|
||||||
const withGroupsAPI = withProps((props) => ({
|
const withGroupsAPI = withProps((props) => ({
|
||||||
addToGroup: (users, groupname) =>
|
addToGroup: (users, groupname) =>
|
||||||
|
@@ -1,132 +1,124 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component, useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import Multiselect from "../Multiselect/Multiselect";
|
import Multiselect from "../Multiselect/Multiselect";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
export class GroupEdit extends Component {
|
const GroupEdit = (props) => {
|
||||||
static get propTypes() {
|
var [selected, setSelected] = useState([]),
|
||||||
return {
|
[changed, setChanged] = useState(false),
|
||||||
location: PropTypes.shape({
|
[added, setAdded] = useState(undefined),
|
||||||
state: PropTypes.shape({
|
[removed, setRemoved] = useState(undefined);
|
||||||
group_data: PropTypes.object,
|
|
||||||
user_data: PropTypes.array,
|
var {
|
||||||
callback: PropTypes.func,
|
addToGroup,
|
||||||
}),
|
removeFromGroup,
|
||||||
}),
|
deleteGroup,
|
||||||
history: PropTypes.shape({
|
refreshGroupsData,
|
||||||
push: PropTypes.func,
|
history,
|
||||||
}),
|
location,
|
||||||
addToGroup: PropTypes.func,
|
} = props;
|
||||||
removeFromGroup: PropTypes.func,
|
|
||||||
deleteGroup: PropTypes.func,
|
if (!location.state) {
|
||||||
};
|
history.push("/groups");
|
||||||
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
var { group_data, user_data, callback } = location.state;
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
selected: [],
|
|
||||||
changed: false,
|
|
||||||
added: undefined,
|
|
||||||
removed: undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
if (!(group_data && user_data)) return <div></div>;
|
||||||
if (!this.props.location.state) {
|
|
||||||
this.props.history.push("/groups");
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
var { group_data, user_data, callback } = this.props.location.state;
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||||
|
<h3>Editing Group {group_data.name}</h3>
|
||||||
|
<br></br>
|
||||||
|
<div className="alert alert-info">Select group members</div>
|
||||||
|
<Multiselect
|
||||||
|
options={user_data.map((e) => e.name)}
|
||||||
|
value={group_data.users}
|
||||||
|
onChange={(selection, options) => {
|
||||||
|
setSelected(selection);
|
||||||
|
setChanged(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<br></br>
|
||||||
|
<button id="return" className="btn btn-light">
|
||||||
|
<Link to="/groups">Back</Link>
|
||||||
|
</button>
|
||||||
|
<span> </span>
|
||||||
|
<button
|
||||||
|
id="submit"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => {
|
||||||
|
// check for changes
|
||||||
|
if (!changed) {
|
||||||
|
history.push("/groups");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var {
|
let new_users = selected.filter(
|
||||||
addToGroup,
|
(e) => !group_data.users.includes(e)
|
||||||
removeFromGroup,
|
);
|
||||||
deleteGroup,
|
let removed_users = group_data.users.filter(
|
||||||
refreshGroupsData,
|
(e) => !selected.includes(e)
|
||||||
} = this.props;
|
);
|
||||||
|
|
||||||
if (!(group_data && user_data)) return <div></div>;
|
setAdded(new_users);
|
||||||
|
setRemoved(removed_users);
|
||||||
|
|
||||||
return (
|
let promiseQueue = [];
|
||||||
<div className="container">
|
if (new_users.length > 0)
|
||||||
<div className="row">
|
promiseQueue.push(addToGroup(new_users, group_data.name));
|
||||||
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
if (removed_users.length > 0)
|
||||||
<h3>Editing Group {group_data.name}</h3>
|
promiseQueue.push(
|
||||||
<br></br>
|
removeFromGroup(removed_users, group_data.name)
|
||||||
<div className="alert alert-info">Select group members</div>
|
|
||||||
<Multiselect
|
|
||||||
options={user_data.map((e) => e.name)}
|
|
||||||
value={group_data.users}
|
|
||||||
onChange={(selection, options) => {
|
|
||||||
this.setState({ selected: selection, changed: true });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<br></br>
|
|
||||||
<button id="return" className="btn btn-light">
|
|
||||||
<Link to="/groups">Back</Link>
|
|
||||||
</button>
|
|
||||||
<span> </span>
|
|
||||||
<button
|
|
||||||
id="submit"
|
|
||||||
className="btn btn-primary"
|
|
||||||
onClick={() => {
|
|
||||||
// check for changes
|
|
||||||
if (!this.state.changed) {
|
|
||||||
this.props.history.push("/groups");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_users = this.state.selected.filter(
|
|
||||||
(e) => !group_data.users.includes(e)
|
|
||||||
);
|
|
||||||
let removed_users = group_data.users.filter(
|
|
||||||
(e) => !this.state.selected.includes(e)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.setState(
|
Promise.all(promiseQueue)
|
||||||
Object.assign({}, this.state, {
|
.then((e) => callback())
|
||||||
added: new_users,
|
.catch((err) => console.log(err));
|
||||||
removed: removed_users,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let promiseQueue = [];
|
history.push("/groups");
|
||||||
if (new_users.length > 0)
|
}}
|
||||||
promiseQueue.push(addToGroup(new_users, group_data.name));
|
>
|
||||||
if (removed_users.length > 0)
|
Apply
|
||||||
promiseQueue.push(
|
</button>
|
||||||
removeFromGroup(removed_users, group_data.name)
|
<button
|
||||||
);
|
className="btn btn-danger"
|
||||||
|
style={{ float: "right" }}
|
||||||
Promise.all(promiseQueue)
|
onClick={() => {
|
||||||
.then((e) => callback())
|
var groupName = group_data.name;
|
||||||
.catch((err) => console.log(err));
|
deleteGroup(groupName)
|
||||||
|
.then(refreshGroupsData())
|
||||||
this.props.history.push("/groups");
|
.then(history.push("/groups"))
|
||||||
}}
|
.catch((err) => console.log(err));
|
||||||
>
|
}}
|
||||||
Apply
|
>
|
||||||
</button>
|
Delete Group
|
||||||
<button
|
</button>
|
||||||
className="btn btn-danger"
|
<br></br>
|
||||||
style={{ float: "right" }}
|
<br></br>
|
||||||
onClick={() => {
|
|
||||||
var groupName = group_data.name;
|
|
||||||
deleteGroup(groupName)
|
|
||||||
.then(refreshGroupsData())
|
|
||||||
.then(this.props.history.push("/groups"))
|
|
||||||
.catch((err) => console.log(err));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Delete Group
|
|
||||||
</button>
|
|
||||||
<br></br>
|
|
||||||
<br></br>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
GroupEdit.propTypes = {
|
||||||
|
location: PropTypes.shape({
|
||||||
|
state: PropTypes.shape({
|
||||||
|
group_data: PropTypes.object,
|
||||||
|
user_data: PropTypes.array,
|
||||||
|
callback: PropTypes.func,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
history: PropTypes.shape({
|
||||||
|
push: PropTypes.func,
|
||||||
|
}),
|
||||||
|
addToGroup: PropTypes.func,
|
||||||
|
removeFromGroup: PropTypes.func,
|
||||||
|
deleteGroup: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GroupEdit;
|
||||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user