pull/1075/head
Piero Toffanin 2021-10-19 11:08:46 -04:00
rodzic 0db85bba66
commit 31006b9373
3 zmienionych plików z 105 dodań i 14 usunięć

Wyświetl plik

@ -27,8 +27,8 @@ tasks_router = routers.NestedSimpleRouter(router, r'projects', lookup='project')
tasks_router.register(r'tasks', TaskViewSet, base_name='projects-tasks')
admin_router = routers.DefaultRouter()
admin_router.register(r'admin/users', UserViewSet, basename='user')
admin_router.register(r'admin/groups', GroupViewSet, basename='group')
admin_router.register(r'admin/users', UserViewSet, base_name='admin-users')
admin_router.register(r'admin/groups', GroupViewSet, base_name='admin-groups')
urlpatterns = [
url(r'processingnodes/options/$', ProcessingNodeOptionsView.as_view()),

Wyświetl plik

@ -26,10 +26,14 @@ class EditPermissionsPanel extends React.Component {
loading: false,
permissions: [],
validUsernames: {},
validatingUser: false
validatingUser: false,
validationUnavailable: false
};
this.backgroundFailedColor = Css.getValue('btn-danger', 'backgroundColor');
this.autocompleteBorderColor = Css.getValue('btn-default', 'backgroundColor');
this.backgroundColor = Css.getValue('theme-secondary', 'backgroundColor');
this.highlightColor = Css.getValue('theme-background-highlight', 'backgroundColor');
}
loadPermissions = () => {
@ -49,7 +53,7 @@ class EditPermissionsPanel extends React.Component {
});
}
validateUsername = (username) => {
autocomplete = (perm) => {
if (this.validateReq){
this.validateReq.abort();
this.validateReq = null;
@ -60,18 +64,29 @@ class EditPermissionsPanel extends React.Component {
this.validateTimeout = null;
}
this.setState({validatingUser: true});
// Empty case
if (perm.username === ""){
delete(perm.autocomplete);
this.setState({permissions: this.state.permissions});
return;
}
this.setState({validatingUser: true});
this.validateTimeout = setTimeout(() => {
this.validateReq = $.getJSON(`/api/users/?limit=30&search=${encodeURIComponent(username)}`)
this.validateReq = $.getJSON(`/api/users/?limit=30&search=${encodeURIComponent(perm.username)}`)
.done((json) => {
json.forEach(u => {
this.state.validUsernames[u.username] = true;
});
this.setState({validUsernames: this.state.validUsernames});
}).fail(() => {
this.state.permissions.forEach(p => delete(p.autocomplete));
perm.autocomplete = json;
this.setState({validUsernames: this.state.validUsernames, permissions: this.state.permissions});
}).fail(() => {
// Perhaps the user API is not enabled
this.setState({validationUnavailable: true});
}).always(() => {
this.setState({validatingUser: false});
});
@ -88,15 +103,18 @@ class EditPermissionsPanel extends React.Component {
if (this.validateTimeout) clearTimeout(this.validateTimeout);
}
handleChangePermissionRole = e => {
handleChangePermissionRole = perm => {
return e => {
perm.permissions = this.extendedPermissions(e.target.value);
this.setState({permissions: this.state.permissions});
}
}
handleChangePermissionUser = perm => {
return e => {
perm.username = e.target.value;
this.validateUsername(perm.username);
this.autocomplete(perm);
// Update
this.setState({permissions: this.state.permissions});
@ -111,6 +129,14 @@ class EditPermissionsPanel extends React.Component {
else return "";
}
extendedPermissions = simPerm => {
if (simPerm == "rw"){
return ["add", "change", "delete", "view"];
}else if (simPerm == "r"){
return ["view"];
}else return [];
}
permissionLabel = simPerm => {
if (simPerm === "rw") return _("Read/Write");
else if (simPerm === "r") return _("Read");
@ -122,7 +148,7 @@ class EditPermissionsPanel extends React.Component {
}
getColorFor = (username) => {
if (this.state.validatingUser || this.state.validUsernames[username]) return "";
if (this.state.validationUnavailable || this.state.validatingUser || this.state.validUsernames[username]) return "";
else return this.backgroundFailedColor;
}
@ -144,6 +170,31 @@ class EditPermissionsPanel extends React.Component {
}
}
acOnMouseEnter = e => {
e.target.style.backgroundColor = this.highlightColor;
}
acOnMouseLeave = e => {
e.target.style.backgroundColor = "";
}
acOnClick = (perm, acEntry) => {
return e => {
perm.username = acEntry.username;
delete(perm.autocomplete);
this.setState({permissions: this.state.permissions});
}
}
onBlur = perm => {
return e => {
setTimeout(() => {
delete(perm.autocomplete);
this.setState({permissions: this.state.permissions});
}, 150);
}
}
render() {
const permissions = this.state.permissions.map((p, i) => <form autoComplete="off" key={i}>
<div className="permission">
@ -154,17 +205,24 @@ class EditPermissionsPanel extends React.Component {
onChange={this.handleChangePermissionUser(p)}
type="text"
autoComplete="off"
onBlur={this.onBlur(p)}
disabled={p.owner}
value={p.username}
className="form-control username"
placeholder={_("Username")}
ref={(domNode) => this.lastTextbox = domNode} />
{p.autocomplete ? <div className="autocomplete" style={{borderColor: this.autocompleteBorderColor, backgroundColor: this.backgroundColor}}>
{p.autocomplete.map(ac => <div key={ac.username} onClick={this.acOnClick(p, ac)} className="ac-entry" onMouseEnter={this.acOnMouseEnter} onMouseLeave={this.acOnMouseLeave} style={{borderColor: this.autocompleteBorderColor}}>
<div className="ac-user">{ac.username}</div>
<div className="ac-email">{ac.email}</div>
</div>)}
</div> : ""}
</div>
<div className="remove">
{!p.owner ? <a onClick={this.handleDeletePermission(p)}><i className="fa fa-times"></i></a> : ""}
</div>
<div className="role-container">
<select disabled={p.owner} className="form-control" value={this.simplifiedPermission(p.permissions)} onChange={this.handleChangePermissionRole}>
<select disabled={p.owner} className="form-control" value={this.simplifiedPermission(p.permissions)} onChange={this.handleChangePermissionRole(p)}>
{this.allPermissions().map(p => <option key={p.key} value={p.key}>{p.label}</option>)}
</select>
</div>

Wyświetl plik

@ -10,7 +10,7 @@
.user-indicator{
position: absolute;
left: 12px;
top: 15px;
top: 16px;
}
.remove{
position: relative;
@ -33,6 +33,39 @@
.username-container{
flex-grow: 0.66;
position: relative;
.autocomplete{
left: 0;
top: 44px;
z-index: 2;
border-width: 1px;
border-style: solid;
width: 100%;
position: absolute;
border-radius: 2px;
max-height: 240px;
overflow-y: auto;
overflow-x: hidden;
.ac-entry{
padding: 10px 15px 10px 15px;
border-bottom-style: solid;
border-bottom-width: 1px;
&:hover{
cursor: pointer;
}
}
.ac-entry:last-child{
border: none;
}
.ac-email{
opacity: 0.8;
}
}
}
.role-container{
flex-grow: 0.33;