mirror of https://github.com/ENSL/ensl_gathers.git
Implemented message browser
This commit is contained in:
parent
880649bdc0
commit
21a8e26147
|
@ -1,5 +1,177 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const MessageBrowser = React.createClass({
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
browserState: "",
|
||||||
|
messages: [],
|
||||||
|
page: 0,
|
||||||
|
limit: 250,
|
||||||
|
search: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleNextPage(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const page = this.state.page;
|
||||||
|
this.setState({ page: page + 1 });
|
||||||
|
this.loadMessages();
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePreviousPage(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const page = this.state.page;
|
||||||
|
if (page < 1) return;
|
||||||
|
this.setState({ page: page - 1 });
|
||||||
|
this.loadMessages();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageHandlers() {
|
||||||
|
let previous;
|
||||||
|
if (this.state.page > 0) {
|
||||||
|
previous = (
|
||||||
|
<a className="btn btn-xs btn-primary add-right"
|
||||||
|
onClick={this.handlePreviousPage}>Prev</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let next;
|
||||||
|
if (this.state.messages.length === this.state.limit) {
|
||||||
|
next = (
|
||||||
|
<a className="btn btn-xs btn-primary"
|
||||||
|
onClick={this.handleNextPage}>Next</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{previous}
|
||||||
|
<span className="add-right">
|
||||||
|
{this.state.page}
|
||||||
|
</span>
|
||||||
|
{next}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMessages() {
|
||||||
|
const limit = this.state.limit;
|
||||||
|
const page = this.state.page;
|
||||||
|
let data = {
|
||||||
|
limit: limit,
|
||||||
|
page: page
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.state.search.length) {
|
||||||
|
data.query = this.state.search;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ browserState: "Retrieving messages"});
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/messages",
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
.done(data => {
|
||||||
|
this.setState({
|
||||||
|
messages: data.messages,
|
||||||
|
browserState: ""
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.fail(error => {
|
||||||
|
console.error(error);
|
||||||
|
this.setState({
|
||||||
|
browserState: `Unable to retrieve messages.`
|
||||||
|
});
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.loadMessages();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateLimit(e) {
|
||||||
|
let newLimit = parseInt(e.target.value, 10);
|
||||||
|
if (isNaN(newLimit) || newLimit > 250) newLimit = 250;
|
||||||
|
this.setState({ limit: newLimit });
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSearch(e) {
|
||||||
|
this.setState({ search: e.target.value });
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let browserState;
|
||||||
|
if (this.state.browserState.length) {
|
||||||
|
browserState = (
|
||||||
|
<div className="col-xs-7">
|
||||||
|
<div className="well">{this.state.browserState}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const messages = this.state.messages.map(message => {
|
||||||
|
return (
|
||||||
|
<tr key={message._id}>
|
||||||
|
<td className="col-xs-2">{(new Date(message.createdAt)).toString()}</td>
|
||||||
|
<td className="col-xs-3">{message.author.username}</td>
|
||||||
|
<td className="col-xs-5">{message.content}</td>
|
||||||
|
<td className="col-xs-2">{message._id}</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-xs-5">
|
||||||
|
<div className="form-horizontal">
|
||||||
|
<div className="form-group">
|
||||||
|
<label className="col-sm-3 control-label">Max Results</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
|
<input type="number" className="form-control"
|
||||||
|
onChange={this.updateLimit}
|
||||||
|
value={this.state.limit}></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label className="col-sm-3 control-label">Search Filter</label>
|
||||||
|
<div className="col-sm-9">
|
||||||
|
<input type="text" className="form-control"
|
||||||
|
onChange={this.updateSearch}
|
||||||
|
value={this.state.search}></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="col-sm-offset-3 col-sm-9">
|
||||||
|
<button
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={this.loadMessages}>Search</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-offset-3 col-sm-9">
|
||||||
|
<p>Page Control</p>
|
||||||
|
{this.pageHandlers()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{browserState}
|
||||||
|
<div className="col-xs-12">
|
||||||
|
<table className="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Author</th>
|
||||||
|
<th>Message</th>
|
||||||
|
<th>ID</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{messages}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var Chatroom = React.createClass({
|
var Chatroom = React.createClass({
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -41,8 +41,7 @@ describe("Messages", () => {
|
||||||
describe("JSON Api", () => {
|
describe("JSON Api", () => {
|
||||||
it ("returns most recent messages", done => {
|
it ("returns most recent messages", done => {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/messages")
|
.get("/api/messages")
|
||||||
.set("Accept", "application/json")
|
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end((error, response) => {
|
.end((error, response) => {
|
||||||
|
@ -56,11 +55,10 @@ describe("Messages", () => {
|
||||||
});
|
});
|
||||||
it ("is sensitive to limit", done => {
|
it ("is sensitive to limit", done => {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/messages")
|
.get("/api/messages")
|
||||||
.query({
|
.query({
|
||||||
limit: 1
|
limit: 1
|
||||||
})
|
})
|
||||||
.set("Accept", "application/json")
|
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end((error, response) => {
|
.end((error, response) => {
|
||||||
|
@ -76,12 +74,11 @@ describe("Messages", () => {
|
||||||
it ("returns a maximum of last 250 messages");
|
it ("returns a maximum of last 250 messages");
|
||||||
it ("is sensitive to pagination", done => {
|
it ("is sensitive to pagination", done => {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/messages")
|
.get("/api/messages")
|
||||||
.query({
|
.query({
|
||||||
limit: 1,
|
limit: 1,
|
||||||
page: 2
|
page: 2
|
||||||
})
|
})
|
||||||
.set("Accept", "application/json")
|
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end((error, response) => {
|
.end((error, response) => {
|
||||||
|
@ -96,11 +93,10 @@ describe("Messages", () => {
|
||||||
});
|
});
|
||||||
it ("is sensitive to search terms", done => {
|
it ("is sensitive to search terms", done => {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/messages")
|
.get("/api/messages")
|
||||||
.query({
|
.query({
|
||||||
query: "5"
|
query: "5"
|
||||||
})
|
})
|
||||||
.set("Accept", "application/json")
|
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end((error, response) => {
|
.end((error, response) => {
|
||||||
|
@ -119,7 +115,6 @@ describe("Messages", () => {
|
||||||
it ("renders message browser", done => {
|
it ("renders message browser", done => {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/messages")
|
.get("/messages")
|
||||||
.set("Accept", "text/html; charset=utf-8")
|
|
||||||
.expect("Content-Type", /html/)
|
.expect("Content-Type", /html/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end((error, response) => {
|
.end((error, response) => {
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
<div id="wrapper">
|
|
||||||
{{>menu}}
|
|
||||||
<div style="min-height: 750px;">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row" id="authenticating">
|
|
||||||
<div class="col-lg-6 col-lg-offset-3">
|
|
||||||
<div class="add-top jumbotron jumbo-auth text-center">
|
|
||||||
<div>
|
|
||||||
<img src="/images/ensl_logo.png" class="jumbo-img" alt="ENSL Logo" />
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<h3>Authenticating your ENSL account</h3>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<img src="/images/spinner.svg" class="spinner" alt="Loading" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row" id="gather-banned" style="display:none;">
|
|
||||||
<div class="col-lg-6 col-lg-offset-3">
|
|
||||||
<div class="add-top jumbotron jumbo-auth text-center">
|
|
||||||
<div>
|
|
||||||
<img src="/images/ensl_logo.png" alt="ENSL Logo" />
|
|
||||||
</div>
|
|
||||||
<h3>You're currently barred from joining gathers</h3>
|
|
||||||
<h3><small>Either wait for the ban to expire or talk to an admin to get it lifted</small></h3>
|
|
||||||
<br />
|
|
||||||
<p><a class="btn btn-primary btn-lg" href="{{ redirect }}" role="button">See the ban list</a></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row" id="auth-required" style="display:none;">
|
|
||||||
<div class="col-lg-6 col-lg-offset-3">
|
|
||||||
<div class="add-top jumbotron jumbo-auth text-center">
|
|
||||||
<div>
|
|
||||||
<img src="/images/ensl_logo.png" alt="ENSL Logo" />
|
|
||||||
</div>
|
|
||||||
<h3>You need to be logged in to the ENSL website ({{ redirect }}) to access gathers</h3>
|
|
||||||
<h3><small>If you are logged on, try visiting a few pages on ENSL.org so the server can update your cookies</small></h3>
|
|
||||||
<h3><small>If this error persists please contact an admin to fix it</small></h3>
|
|
||||||
<br />
|
|
||||||
<p><a class="btn btn-primary btn-lg" href="{{ redirect }}" role="button">Go to website</a></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2 hidden-xs">
|
|
||||||
<ul class="nav" id="side-menu"></ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4" id="chatroom"></div>
|
|
||||||
<div class="col-md-6" id="gathers"></div>
|
|
||||||
<div class="col-md-6 col-md-offset-6" id="archived-gathers"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{>foot}}
|
|
|
@ -6,10 +6,18 @@
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h2>Message Browser</h2>
|
<h2>Message Browser</h2>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
|
<div id="message-browser"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
React.render(React.createElement(MessageBrowser, null), document.getElementById("message-browser"));
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in New Issue