mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-12 12:33:02 +00:00
Updated code to fit with latest version
This commit is contained in:
@@ -5,6 +5,7 @@ import PropTypes from "prop-types";
|
|||||||
import GroupSelect from "../GroupSelect/GroupSelect";
|
import GroupSelect from "../GroupSelect/GroupSelect";
|
||||||
import DynamicTable from "../DynamicTable/DynamicTable";
|
import DynamicTable from "../DynamicTable/DynamicTable";
|
||||||
|
|
||||||
|
|
||||||
function hasDuplicates(array) {
|
function hasDuplicates(array) {
|
||||||
var valuesSoFar = Object.create(null);
|
var valuesSoFar = Object.create(null);
|
||||||
for (var i = 0; i < array.length; ++i) {
|
for (var i = 0; i < array.length; ++i) {
|
||||||
@@ -17,6 +18,8 @@ function hasDuplicates(array) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const GroupEdit = (props) => {
|
const GroupEdit = (props) => {
|
||||||
var [selected, setSelected] = useState([]),
|
var [selected, setSelected] = useState([]),
|
||||||
[changed, setChanged] = useState(false),
|
[changed, setChanged] = useState(false),
|
||||||
@@ -52,8 +55,8 @@ const GroupEdit = (props) => {
|
|||||||
|
|
||||||
var { group_data } = location.state;
|
var { group_data } = location.state;
|
||||||
var [propobject, setProp] = useState(group_data.properties);
|
var [propobject, setProp] = useState(group_data.properties);
|
||||||
var [propkeys, setPropKeys] = useState([]);
|
var [propkeys, setPropKeys]= useState([]);
|
||||||
var [propvalues, setPropValues] = useState([]);
|
var [propvalues, setPropValues]= useState([]);
|
||||||
|
|
||||||
if (!group_data) return <div></div>;
|
if (!group_data) return <div></div>;
|
||||||
|
|
||||||
@@ -74,24 +77,19 @@ const GroupEdit = (props) => {
|
|||||||
setChanged(true);
|
setChanged(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<div className="container">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
|
||||||
<div className="alert alert-info">Manage group properties</div>
|
<div className="alert alert-info">Manage group properties</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
|
||||||
<DynamicTable
|
<DynamicTable
|
||||||
current_propobject={group_data.properties}
|
current_propobject={group_data.properties}
|
||||||
setProp={setProp}
|
setProp={setProp}
|
||||||
setPropKeys={setPropKeys}
|
setPropKeys={setPropKeys}
|
||||||
setPropValues={setPropValues}
|
setPropValues={setPropValues}
|
||||||
setChanged={setChanged}
|
setChanged ={setChanged}
|
||||||
//Add keys
|
//Add keys
|
||||||
/>
|
/>
|
||||||
</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">
|
||||||
<button id="return" className="btn btn-light">
|
<button id="return" className="btn btn-light">
|
||||||
@@ -121,24 +119,22 @@ const GroupEdit = (props) => {
|
|||||||
promiseQueue.push(
|
promiseQueue.push(
|
||||||
removeFromGroup(removed_users, group_data.name)
|
removeFromGroup(removed_users, group_data.name)
|
||||||
);
|
);
|
||||||
if (hasDuplicates(propkeys) == true) {
|
if (hasDuplicates(propkeys)==true){
|
||||||
error.textContent = "Duplicate key found!";
|
error.textContent = "Duplicate key found!"
|
||||||
error.style.color = "red";
|
error.style.color = "red"
|
||||||
} else {
|
} else{
|
||||||
error.textContent = "";
|
error.textContent = ""
|
||||||
propkeys.forEach((key, i) => (propobject[key] = propvalues[i]));
|
propkeys.forEach((key, i) => propobject[key] = propvalues[i]);
|
||||||
}
|
}
|
||||||
if (
|
if (propobject != group_data.properties && hasDuplicates(propkeys)== false) {
|
||||||
propobject != group_data.properties &&
|
promiseQueue.push(
|
||||||
hasDuplicates(propkeys) == false
|
updateProp(propobject, group_data.name)
|
||||||
) {
|
);
|
||||||
promiseQueue.push(updateProp(propobject, group_data.name));
|
|
||||||
}
|
}
|
||||||
Promise.all(promiseQueue)
|
Promise.all(promiseQueue)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
updateGroups(0, limit).then((data) =>
|
updateGroups(0, limit)
|
||||||
dispatchPageUpdate(data, 0)
|
.then((data) => dispatchPageUpdate(data, 0));
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
}}
|
}}
|
||||||
|
@@ -298,9 +298,10 @@ class APIHandler(BaseHandler):
|
|||||||
'name': group.name,
|
'name': group.name,
|
||||||
'roles': [r.name for r in group.roles],
|
'roles': [r.name for r in group.roles],
|
||||||
'users': [u.name for u in group.users],
|
'users': [u.name for u in group.users],
|
||||||
|
'properties': group.properties
|
||||||
}
|
}
|
||||||
access_map = {
|
access_map = {
|
||||||
'read:groups': {'kind', 'name', 'users'},
|
'read:groups': {'kind', 'name', 'users','properties'},
|
||||||
'read:groups:name': {'kind', 'name'},
|
'read:groups:name': {'kind', 'name'},
|
||||||
'read:roles:groups': {'kind', 'name', 'roles'},
|
'read:roles:groups': {'kind', 'name', 'roles'},
|
||||||
}
|
}
|
||||||
|
@@ -180,7 +180,6 @@ class GroupUsersAPIHandler(_GroupAPIHandler):
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.write(json.dumps(self.group_model(group)))
|
self.write(json.dumps(self.group_model(group)))
|
||||||
|
|
||||||
|
|
||||||
class GroupPropertiesAPIHandler(_GroupAPIHandler):
|
class GroupPropertiesAPIHandler(_GroupAPIHandler):
|
||||||
"""Modify a group's properties"""
|
"""Modify a group's properties"""
|
||||||
|
|
||||||
@@ -188,7 +187,7 @@ class GroupPropertiesAPIHandler(_GroupAPIHandler):
|
|||||||
def put(self, group_name):
|
def put(self, group_name):
|
||||||
group = self.find_group(group_name)
|
group = self.find_group(group_name)
|
||||||
data = self.get_json_body()
|
data = self.get_json_body()
|
||||||
# self._check_group_model(data)
|
#self._check_group_model(data)
|
||||||
if not isinstance(data, dict):
|
if not isinstance(data, dict):
|
||||||
raise web.HTTPError(400, "Must specify properties")
|
raise web.HTTPError(400, "Must specify properties")
|
||||||
self.log.info("Updating properties of group %s", group_name)
|
self.log.info("Updating properties of group %s", group_name)
|
||||||
@@ -196,7 +195,6 @@ class GroupPropertiesAPIHandler(_GroupAPIHandler):
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.write(json.dumps(self.group_model(group)))
|
self.write(json.dumps(self.group_model(group)))
|
||||||
|
|
||||||
|
|
||||||
default_handlers = [
|
default_handlers = [
|
||||||
(r"/api/groups", GroupListAPIHandler),
|
(r"/api/groups", GroupListAPIHandler),
|
||||||
(r"/api/groups/([^/]+)", GroupAPIHandler),
|
(r"/api/groups/([^/]+)", GroupAPIHandler),
|
||||||
|
@@ -222,9 +222,8 @@ class Group(Base):
|
|||||||
__tablename__ = 'groups'
|
__tablename__ = 'groups'
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
name = Column(Unicode(255), unique=True)
|
name = Column(Unicode(255), unique=True)
|
||||||
# The properties column contains key:value pairs that represent group settings and their values. Example: {"ram": 8, "cpu": 4}
|
|
||||||
properties = Column(JSONDict, default={})
|
|
||||||
users = relationship('User', secondary='user_group_map', backref='groups')
|
users = relationship('User', secondary='user_group_map', backref='groups')
|
||||||
|
properties = Column(JSONDict, default= {})
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s %s (%i users)>" % (
|
return "<%s %s (%i users)>" % (
|
||||||
|
@@ -1613,20 +1613,8 @@ async def test_groups_list(app):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
reply = r.json()
|
reply = r.json()
|
||||||
assert reply == [
|
assert reply == [
|
||||||
{
|
{'kind': 'group', 'name': 'alphaflight', 'users': [], 'roles': [], 'properties': {}},
|
||||||
'kind': 'group',
|
{'kind': 'group', 'name': 'betaflight', 'users': [], 'roles': [],'properties': {}},
|
||||||
'name': 'alphaflight',
|
|
||||||
'users': [],
|
|
||||||
'roles': [],
|
|
||||||
'properties': {},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'kind': 'group',
|
|
||||||
'name': 'betaflight',
|
|
||||||
'users': [],
|
|
||||||
'roles': [],
|
|
||||||
'properties': {},
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Test offset for pagination
|
# Test offset for pagination
|
||||||
@@ -1634,15 +1622,7 @@ async def test_groups_list(app):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
reply = r.json()
|
reply = r.json()
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert reply == [
|
assert reply == [{'kind': 'group', 'name': 'betaflight', 'users': [], 'roles': [],'properties': {}}]
|
||||||
{
|
|
||||||
'kind': 'group',
|
|
||||||
'name': 'betaflight',
|
|
||||||
'users': [],
|
|
||||||
'roles': [],
|
|
||||||
'properties': {},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
r = await api_request(app, "groups?offset=10")
|
r = await api_request(app, "groups?offset=10")
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
@@ -1654,21 +1634,13 @@ async def test_groups_list(app):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
reply = r.json()
|
reply = r.json()
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert reply == [
|
assert reply == [{'kind': 'group', 'name': 'alphaflight', 'users': [], 'roles': [],'properties': {}}]
|
||||||
{
|
|
||||||
'kind': 'group',
|
|
||||||
'name': 'alphaflight',
|
|
||||||
'users': [],
|
|
||||||
'roles': [],
|
|
||||||
'properties': {},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
# 0 is rounded up to 1
|
# 0 is rounded up to 1
|
||||||
r = await api_request(app, "groups?limit=0")
|
r = await api_request(app, "groups?limit=0")
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
reply = r.json()
|
reply = r.json()
|
||||||
assert reply == [{'kind': 'group', 'name': 'alphaflight', 'users': [], 'roles': []}]
|
assert reply == [{'kind': 'group', 'name': 'alphaflight', 'users': [], 'roles': [],'properties': {}}]
|
||||||
|
|
||||||
|
|
||||||
@mark.group
|
@mark.group
|
||||||
@@ -1797,16 +1769,16 @@ async def test_group_add_delete_users(app):
|
|||||||
|
|
||||||
group = orm.Group.find(db, name='alphaflight')
|
group = orm.Group.find(db, name='alphaflight')
|
||||||
assert sorted(u.name for u in group.users) == sorted(names[2:])
|
assert sorted(u.name for u in group.users) == sorted(names[2:])
|
||||||
|
|
||||||
|
|
||||||
@mark.group
|
@mark.group
|
||||||
async def test_group_add_properties(app):
|
async def test_group_add_properties(app):
|
||||||
db = app.db
|
db = app.db
|
||||||
# must specify users
|
group = orm.Group(name='alphaflight')
|
||||||
|
app.db.add(group)
|
||||||
|
app.db.commit()
|
||||||
r = await api_request(app, 'groups/alphaflight/properties', method='put', data='{}')
|
r = await api_request(app, 'groups/alphaflight/properties', method='put', data='{}')
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
properties_object = {'cpu': "8", 'ram': "4", 'image': "testimage"}
|
properties_object = {'cpu': "8", 'ram': "4", 'image':"testimage"}
|
||||||
|
|
||||||
r = await api_request(
|
r = await api_request(
|
||||||
app,
|
app,
|
||||||
@@ -1817,10 +1789,10 @@ async def test_group_add_properties(app):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
group = orm.Group.find(db, name='alphaflight')
|
group = orm.Group.find(db, name='alphaflight')
|
||||||
|
|
||||||
assert sorted(k for k in group.properties) == sorted(k for k in properties_object)
|
|
||||||
assert sorted(group.properties[k] for k in group.properties) == sorted(
|
assert sorted([k for k in group.properties]) == sorted([k for k in properties_object])
|
||||||
properties_object[k] for k in properties_object
|
assert sorted([group.properties[k] for k in group.properties]) == sorted([properties_object[k] for k in properties_object])
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
|
Reference in New Issue
Block a user