Update the admin panel

This commit is contained in:
Grégoire Delattre 2019-05-15 14:39:34 +02:00 committed by Gogs
parent 56bc8d335c
commit 2897f73cb9
3 changed files with 176 additions and 229 deletions

View File

@ -1,37 +1,33 @@
import React from "react" import React from "react"
import PropTypes from "prop-types"
import { connect } from "react-redux" import { connect } from "react-redux"
import { bindActionCreators } from "redux" import { bindActionCreators } from "redux"
import { updateUser } from "../../actions/admins" import { updateUser } from "../../actions/admins"
import Modules from "../modules/modules" import Modules from "../modules/modules"
import UserList from "./users" import { UserList } from "./users"
import Stats from "./stats" import { Stats } from "./stats"
function mapStateToProps(state) { const AdminPanel = props => (
return { <React.Fragment>
users : state.adminStore.get("users"), <Stats stats={props.stats}/>
stats : state.adminStore.get("stats"), <UserList users={props.users} updateUser={props.updateUser}/>
modules : state.adminStore.get("modules"), <Modules modules={props.modules}/>
}; </React.Fragment>
} )
const mapDispatchToProps = (dipatch) => AdminPanel.propTypes = {
stats: PropTypes.object,
users: PropTypes.object,
modules: PropTypes.object,
updateUser: PropTypes.func,
};
const mapStateToProps = state => ({
users: state.adminStore.get("users"),
stats: state.adminStore.get("stats"),
modules: state.adminStore.get("modules"),
});
const mapDispatchToProps = dipatch =>
bindActionCreators({ updateUser }, dipatch) bindActionCreators({ updateUser }, dipatch)
function AdminPanel(props) {
return (
<div>
<Stats
stats={props.stats}
/>
<UserList
users={props.users}
updateUser={props.updateUser}
/>
<Modules
modules={props.modules}
/>
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(AdminPanel); export default connect(mapStateToProps, mapDispatchToProps)(AdminPanel);

View File

@ -1,7 +1,7 @@
import React from "react" import React from "react"
import PropTypes from "prop-types"
export default function Stats(props) { export const Stats = props => (
return (
<div> <div>
<h2 className="hidden-xs">Stats</h2> <h2 className="hidden-xs">Stats</h2>
<Stat <Stat
@ -23,11 +23,10 @@ export default function Stats(props) {
torrentCountById={props.stats.get("episodes_torrents_count_by_id")} torrentCountById={props.stats.get("episodes_torrents_count_by_id")}
/> />
</div> </div>
); )
} Stats.propTypes = { stats: PropTypes.object }
function Stat(props) { const Stat = props => (
return (
<div className="col-xs-4"> <div className="col-xs-4">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-heading"> <div className="panel-heading">
@ -41,10 +40,13 @@ function Stat(props) {
</div> </div>
</div> </div>
</div> </div>
); )
} Stat.propTypes = {
name: PropTypes.string,
count: PropTypes.number,
};
function TorrentsStat(props) { const TorrentsStat = function(props) {
if (props.data.torrentCount === undefined) { if (props.data.torrentCount === undefined) {
return (<span>No torrents</span>); return (<span>No torrents</span>);
} }
@ -57,3 +59,4 @@ function TorrentsStat(props) {
</span> </span>
); );
} }
TorrentsStat.propTypes = { data: PropTypes.object };

View File

@ -1,10 +1,11 @@
import React from "react" import React, { useState } from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
import { Button, Modal } from "react-bootstrap" import { Button, Modal } from "react-bootstrap"
import Toggle from "react-bootstrap-toggle"; import Toggle from "react-bootstrap-toggle";
export default function UserList(props) { export const UserList = props => (
return (
<div> <div>
<h2 className="hidden-xs">Users</h2> <h2 className="hidden-xs">Users</h2>
<h3 className="visible-xs">Users</h3> <h3 className="visible-xs">Users</h3>
@ -21,169 +22,116 @@ export default function UserList(props) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{props.users.map(function(el, index) { {props.users.map((el, index) =>
return ( <User key={index} data={el} updateUser={props.updateUser}/>)}
<User
key={index}
data={el}
updateUser={props.updateUser}
/>
);
})}
</tbody> </tbody>
</table> </table>
</div> </div>
); );
} UserList.propTypes = {
users: PropTypes.PropTypes.instanceOf(List),
updateUser: PropTypes.func,
};
function User(props) { const User = function(props) {
const polochonConfig = props.data.get("RawConfig").get("polochon"); const polochonConfig = props.data.get("RawConfig").get("polochon");
const polochonURL = polochonConfig ? polochonConfig.get("url") : "-"; const polochonUrl = polochonConfig ? polochonConfig.get("url") : "-";
const polochonToken = polochonConfig ? polochonConfig.get("token") : "-"; const polochonToken = polochonConfig ? polochonConfig.get("token") : "-";
return ( return (
<tr> <tr>
<td>{props.data.get("id")}</td> <td>{props.data.get("id")}</td>
<td>{props.data.get("Name")}</td> <td>{props.data.get("Name")}</td>
<td><UserActivationStatus data={props.data}/></td> <td><UserActivationStatus activated={props.data.get("Activated")}/></td>
<td><UserAdminStatus data={props.data}/></td> <td><UserAdminStatus admin={props.data.get("Admin")}/></td>
<td>{polochonURL}</td> <td>{polochonUrl}</td>
<td>{polochonToken}</td> <td>{polochonToken}</td>
<td> <td>
<UserEdit <UserEdit
data={props.data} data={props.data}
updateUser={props.updateUser} updateUser={props.updateUser}
polochonUrl={polochonUrl}
polochonToken={polochonToken}
/> />
</td> </td>
</tr> </tr>
); );
} }
User.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func,
};
function UserAdminStatus(props) { const UserAdminStatus = props => (
const admin = props.data.get("Admin"); <span className={props.admin ? "fa fa-check" : "fa fa-times"}></span>
const className = admin ? "fa fa-check" : "fa fa-times"; );
return (<span className={className}></span>); UserAdminStatus.propTypes = { admin: PropTypes.bool.isRequired };
}
function UserActivationStatus(props) { const UserActivationStatus = props => (
const activated = props.data.get("Activated"); <span className={props.activated ? "fa fa-check" : "fa fa-times text-danger"}></span>
const className = activated ? "fa fa-check" : "fa fa-times text-danger"; );
return (<span className={className}></span>); UserActivationStatus.propTypes = { activated: PropTypes.bool.isRequired };
}
class UserEdit extends React.PureComponent { function UserEdit(props) {
constructor(props) { const [modal, setModal] = useState(false);
super(props); const [admin, setAdmin] = useState(props.data.get("Admin"));
const [activated, setActivated] = useState(props.data.get("Activated"));
const [url, setUrl] = useState(props.polochonUrl);
const [token, setToken] = useState(props.polochonToken);
// User props const handleSubmit = function(e) {
const polochonConfig = props.data.get("RawConfig").get("polochon");
const polochonUrl = polochonConfig ? polochonConfig.get("url") : "";
const polochonToken = polochonConfig ? polochonConfig.get("token") : "";
// Functions
this.showModal = this.showModal.bind(this);
this.hideModal = this.hideModal.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleUrlInput = this.handleUrlInput.bind(this);
this.handleTokenInput = this.handleTokenInput.bind(this);
this.handleActivatedToggle = this.handleActivatedToggle.bind(this);
this.handleAdminToggle = this.handleAdminToggle.bind(this);
this.state = {
showModal: false,
polochonUrl: polochonUrl,
polochonToken: polochonToken,
activated: props.data.get("Activated"),
admin: props.data.get("Admin"),
};
}
showModal() {
this.setState({ showModal: true });
}
hideModal() {
this.setState({ showModal: false });
}
handleSubmit(e) {
if (e) { e.preventDefault(); } if (e) { e.preventDefault(); }
this.props.updateUser({ props.updateUser({
userId: this.props.data.get("id"), userId: props.data.get("id"),
admin: this.state.admin, admin: admin,
activated: this.state.activated, activated: activated,
polochonUrl: this.state.polochonUrl, polochonUrl: url,
polochonToken: this.state.polochonToken, polochonToken: token,
}); });
this.setState({ showModal: false }); setModal(false);
} };
handleTokenInput() {
this.setState({ polochonToken: this.refs.polochonToken.value });
}
handleUrlInput() {
this.setState({ polochonUrl: this.refs.polochonUrl.value });
}
handleActivatedToggle() {
this.setState({ activated: !this.state.activated });
}
handleAdminToggle() {
this.setState({ admin: !this.state.admin });
}
render() {
return ( return (
<span> <span>
<span className="fa fa-pencil clickable" onClick={this.showModal}></span> <span className="fa fa-pencil clickable" onClick={() => setModal(true)}></span>
<Modal show={this.state.showModal} onHide={this.hideModal}> <Modal show={modal} onHide={() => setModal(false)}>
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title> <Modal.Title>
<i className="fa fa-pencil"></i> <i className="fa fa-pencil"></i>
&nbsp; Edit user - {this.props.data.get("Name")} &nbsp; Edit user - {props.data.get("Name")}
</Modal.Title> </Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body bsClass="modal-body admin-edit-user-modal"> <Modal.Body bsClass="modal-body admin-edit-user-modal">
<form className="form-horizontal" onSubmit={(ev) => this.handleSubmit(ev)}> <form className="form-horizontal" onSubmit={(ev) => handleSubmit(ev)}>
<div className="form-group"> <div className="form-group">
<label>Account status</label> <label>Account status</label>
<Toggle <Toggle className="pull-right" on="Activated" off="Deactivated" active={activated} onClick={() => setActivated(!activated)}
className="pull-right"
on="Activated"
off="Deactivated"
active={this.state.activated}
onClick={this.handleActivatedToggle}
/> />
</div> </div>
<div className="form-group"> <div className="form-group">
<label>Admin status</label> <label>Admin status</label>
<Toggle <Toggle className="pull-right" on="Admin" off="User" active={admin} onClick={() => setAdmin(!admin)} />
className="pull-right"
on="Admin"
off="User"
active={this.state.admin}
onClick={this.handleAdminToggle}
/>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="control-label">Polochon URL</label> <label className="control-label">Polochon URL</label>
<input <input className="form-control" value={url} onChange={(e) => setUrl(e.target.value)}/>
className="form-control"
value={this.state.polochonUrl}
onChange={this.handleUrlInput}
ref="polochonUrl"
/>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="control-label">Polochon token</label> <label className="control-label">Polochon token</label>
<input <input className="form-control" value={token} onChange={(e) => setToken(e.target.value)} />
className="form-control"
value={this.state.polochonToken}
onChange={this.handleTokenInput}
ref="polochonToken"
/>
</div> </div>
</form> </form>
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<Button bsStyle="success" onClick={this.handleSubmit}>Apply</Button> <Button bsStyle="success" onClick={handleSubmit}>Apply</Button>
<Button onClick={this.hideModal}>Close</Button> <Button onClick={() => setModal(false)}>Close</Button>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
</span> </span>
); );
}
} }
UserEdit.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func,
polochonUrl: PropTypes.string,
polochonToken: PropTypes.string,
};