Permission stuff
This commit is contained in:
@@ -104,6 +104,14 @@ export default class API {
|
||||
}
|
||||
|
||||
async sendTestMail(receiver) {
|
||||
return this.apiCall("sendTestMail", { receiver: receiver });
|
||||
return this.apiCall("mail/test", { receiver: receiver });
|
||||
}
|
||||
|
||||
async fetchPermissions() {
|
||||
return this.apiCall("permission/fetch");
|
||||
}
|
||||
|
||||
async savePermissions(permissions) {
|
||||
return this.apiCall("permission/save", { permissions: permissions });
|
||||
}
|
||||
};
|
||||
@@ -209,8 +209,26 @@ export default class Overview extends React.Component {
|
||||
<li><b>Load Average</b>: { loadAvg }</li>
|
||||
<li><b>Database</b>: { this.state.server["database"] }</li>
|
||||
<li><b>Mail</b>: { this.state.server["mail"] === true
|
||||
? <span>OK<Icon icon={""} className={"ml-2"}/></span>
|
||||
: <Link to={"/admin/settings"}>Not configured</Link>}</li>
|
||||
? <span>
|
||||
OK
|
||||
<Icon icon={"check-circle"} className={"ml-2 text-success"}/>
|
||||
</span>
|
||||
: <span>
|
||||
<Link to={"/admin/settings"}>Not configured</Link>
|
||||
<Icon icon={"times-circle"} className={"ml-2 text-danger"}/>
|
||||
</span>}
|
||||
</li>
|
||||
<li>
|
||||
<b>Google reCaptcha</b>: { this.state.server["reCaptcha"] === true
|
||||
? <span>
|
||||
OK
|
||||
<Icon icon={"check-circle"} className={"ml-2 text-success"}/>
|
||||
</span>
|
||||
: <span>
|
||||
<Link to={"/admin/settings"}>Not configured</Link>
|
||||
<Icon icon={"times-circle"} className={"ml-2 text-danger"}/>
|
||||
</span>}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as React from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import Icon from "../elements/icon";
|
||||
import Alert from "../elements/alert";
|
||||
import ReactTooltip from "react-tooltip";
|
||||
|
||||
export default class PermissionSettings extends React.Component {
|
||||
|
||||
@@ -10,11 +12,127 @@ export default class PermissionSettings extends React.Component {
|
||||
this.state = {
|
||||
alerts: [],
|
||||
permissions: [],
|
||||
groups: {}
|
||||
groups: {},
|
||||
isSaving: false,
|
||||
isResetting: false
|
||||
};
|
||||
|
||||
this.parent = {
|
||||
api: props.api
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchPermissions()
|
||||
}
|
||||
|
||||
fetchPermissions() {
|
||||
this.parent.api.fetchPermissions().then((res) => {
|
||||
if (!res.success) {
|
||||
let alerts = this.state.alerts.slice();
|
||||
alerts.push({ message: res.msg, title: "Error fetching permissions" });
|
||||
this.setState({...this.state, alerts: alerts, isResetting: false});
|
||||
} else {
|
||||
this.setState({...this.state, groups: res.groups, permissions: res.permissions, isResetting: false});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
removeAlert(i) {
|
||||
if (i >= 0 && i < this.state.alerts.length) {
|
||||
let alerts = this.state.alerts.slice();
|
||||
alerts.splice(i, 1);
|
||||
this.setState({...this.state, alerts: alerts});
|
||||
}
|
||||
}
|
||||
|
||||
onChangeMethod(e, index) {
|
||||
if (index < 0 || index >= this.state.permissions.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let value = e.target.value;
|
||||
let newPermissions = this.state.permissions.slice();
|
||||
newPermissions[index].method = value;
|
||||
this.setState({ ...this.state, permissions: newPermissions })
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let alerts = [];
|
||||
for (let i = 0; i < this.state.alerts.length; i++) {
|
||||
alerts.push(<Alert key={"error-" + i} onClose={() => this.removeAlert(i)} {...this.state.alerts[i]}/>)
|
||||
}
|
||||
|
||||
let th = [];
|
||||
th.push(<th key={"th-method"}>Method</th>);
|
||||
th.push(<th key={"th-everyone"} className={"text-center"}>Everyone</th>);
|
||||
|
||||
for (let groupId in this.state.groups) {
|
||||
if (this.state.groups.hasOwnProperty(groupId)) {
|
||||
let groupName = this.state.groups[groupId].name;
|
||||
let groupColor = this.state.groups[groupId].color;
|
||||
th.push(
|
||||
<th key={"th-" + groupId} className={"text-center"}>
|
||||
<span key={"group-" + groupId} className={"badge text-white"} style={{backgroundColor: groupColor}}>
|
||||
{groupName}
|
||||
</span>
|
||||
</th>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let tr = [];
|
||||
for (let i = 0; i < this.state.permissions.length; i++) {
|
||||
let permission = this.state.permissions[i];
|
||||
let td = [];
|
||||
|
||||
if (permission.description) {
|
||||
td.push(
|
||||
<td>
|
||||
<ReactTooltip id={"tooltip-" + i} />
|
||||
{ permission.method }
|
||||
<Icon icon={"info-circle"} className={"text-info float-right"}
|
||||
data-tip={permission.description} data-place={"right"} data-type={"info"}
|
||||
data-effect={"solid"} data-for={"tooltip-" + i} />
|
||||
</td>
|
||||
);
|
||||
} else {
|
||||
td.push(
|
||||
<td>
|
||||
<ReactTooltip id={"tooltip-" + i} />
|
||||
<input type={"text"} maxLength={32} value={this.state.permissions[i].method}
|
||||
onChange={(e) => this.onChangeMethod(e, i)} />
|
||||
<Icon icon={"trash"} className={"text-danger float-right"}
|
||||
data-tip={"Delete"} data-place={"right"} data-type={"error"}
|
||||
data-effect={"solid"} data-for={"tooltip-" + i}
|
||||
onClick={() => this.onDeletePermission(i)} style={{cursor: "pointer"}} />
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
td.push(
|
||||
<td key={"td-everyone"} className={"text-center"}>
|
||||
<input type={"checkbox"} checked={this.state.permissions[i].groups.length === 0}
|
||||
onChange={(e) => this.onChangePermission(e, i)}/>
|
||||
</td>
|
||||
);
|
||||
|
||||
for (let groupId in this.state.groups) {
|
||||
if (this.state.groups.hasOwnProperty(groupId)) {
|
||||
groupId = parseInt(groupId);
|
||||
td.push(
|
||||
<td key={"td-" + groupId} className={"text-center"}>
|
||||
<input type={"checkbox"} checked={this.state.permissions[i].groups.includes(groupId)}
|
||||
onChange={(e) => this.onChangePermission(e, i, groupId)}/>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tr.push(<tr key={"permission-" + i}>{td}</tr>);
|
||||
}
|
||||
|
||||
return <>
|
||||
<div className="content-header">
|
||||
<div className="container-fluid">
|
||||
@@ -35,15 +153,110 @@ export default class PermissionSettings extends React.Component {
|
||||
<div className={"content"}>
|
||||
<div className={"row"}>
|
||||
<div className={"col-lg-6 pl-5 pr-5"}>
|
||||
<form>
|
||||
<Link to={"/admin/users"} className={"btn btn-info mt-2 mr-2"}>
|
||||
<Icon icon={"arrow-left"}/>
|
||||
Back
|
||||
</Link>
|
||||
{alerts}
|
||||
<form onSubmit={(e) => e.preventDefault()}>
|
||||
<table className={"table table-bordered table-hover dataTable dtr-inline"}>
|
||||
<thead>
|
||||
<tr role={"row"}>
|
||||
{th}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tr}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className={"mt-2"}>
|
||||
<Link to={"/admin/users"} className={"btn btn-primary"}>
|
||||
<Icon icon={"arrow-left"}/>
|
||||
Back
|
||||
</Link>
|
||||
<button className={"btn btn-info ml-2"} onClick={() => this.onAddPermission()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||
<Icon icon={"plus"}/> Add new Permission
|
||||
</button>
|
||||
<button className={"btn btn-secondary ml-2"} onClick={() => this.onResetPermissions()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||
{ this.state.isResetting ? <span>Resetting <Icon icon={"circle-notch"}/></span> : "Reset" }
|
||||
</button>
|
||||
<button className={"btn btn-success ml-2"} onClick={() => this.onSavePermissions()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||
{ this.state.isSaving ? <span>Saving <Icon icon={"circle-notch"}/></span> : "Save" }
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
|
||||
onAddPermission() {
|
||||
let newPermissions = this.state.permissions.slice();
|
||||
newPermissions.push({ method: "", groups: [], description: null });
|
||||
this.setState({ ...this.state, permissions: newPermissions })
|
||||
}
|
||||
|
||||
onResetPermissions() {
|
||||
this.setState({ ...this.state, isResetting: true });
|
||||
this.fetchPermissions();
|
||||
}
|
||||
|
||||
onSavePermissions() {
|
||||
this.setState({ ...this.state, isSaving: true });
|
||||
|
||||
let permissions = [];
|
||||
for (let i = 0; i < this.state.permissions.length; i++) {
|
||||
let permission = this.state.permissions[i];
|
||||
permissions.push({ method: permission.method, groups: permission.groups });
|
||||
}
|
||||
|
||||
this.parent.api.savePermissions(permissions).then((res) => {
|
||||
if (!res.success) {
|
||||
let alerts = this.state.alerts.slice();
|
||||
alerts.push({ message: res.msg, title: "Error saving permissions" });
|
||||
this.setState({...this.state, alerts: alerts, isSaving: false});
|
||||
} else {
|
||||
this.setState({...this.state, isSaving: false});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onDeletePermission(index) {
|
||||
if (index < 0 || index >= this.state.permissions.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newPermissions = this.state.permissions.slice();
|
||||
newPermissions.splice(index, 1);
|
||||
this.setState({ ...this.state, permissions: newPermissions })
|
||||
}
|
||||
|
||||
onChangePermission(event, index, group = null) {
|
||||
if (index < 0 || index >= this.state.permissions.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let isChecked = event.target.checked;
|
||||
let newPermissions = this.state.permissions.slice();
|
||||
if (group === null) {
|
||||
if (isChecked) {
|
||||
newPermissions[index].groups = [];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isChecked && !newPermissions[index].groups.includes(group)) {
|
||||
newPermissions[index].groups.push(group);
|
||||
} else if(!isChecked) {
|
||||
let indexOf = newPermissions[index].groups.indexOf(group);
|
||||
if (indexOf !== -1) {
|
||||
newPermissions[index].groups.splice(indexOf, 1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ ...this.state, permissions: newPermissions })
|
||||
}
|
||||
};
|
||||
@@ -78,6 +78,7 @@ export default class Settings extends React.Component {
|
||||
return this.state.general.keys.includes(key)
|
||||
|| this.state.mail.keys.includes(key)
|
||||
|| this.state.messages.keys.includes(key)
|
||||
|| this.state.recaptcha.keys.includes(key)
|
||||
|| this.hiddenKeys.includes(key);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user