Add ability to edit sync policy from dashboard

This commit is contained in:
Halla Moore 2016-07-05 15:41:56 -07:00
parent 8b1f012a3c
commit 9c342c0c77
7 changed files with 131 additions and 3 deletions

View file

@ -24,7 +24,7 @@ const forEachAccountList = (forEachCallback) => {
const assignPolicy = (accountId, policy) => {
console.log(`Changing policy for ${accountId} to ${JSON.stringify(policy)}`)
const DatabaseConnector = require('./database-connector');
DatabaseConnector.forShared().then(({Account}) => {
return DatabaseConnector.forShared().then(({Account}) => {
Account.find({where: {id: accountId}}).then((account) => {
account.syncPolicy = policy;
account.save()

View file

@ -2,14 +2,29 @@ const Hapi = require('hapi');
const HapiWebSocket = require('hapi-plugin-websocket');
const Inert = require('inert');
const {DatabaseConnector, PubsubConnector, SchedulerUtils} = require(`nylas-core`);
const fs = require('fs');
const path = require('path');
global.Promise = require('bluebird');
const server = new Hapi.Server();
server.connection({ port: process.env.PORT / 1 + 1 || 5101 });
const attach = (directory) => {
const routesDir = path.join(__dirname, directory)
fs.readdirSync(routesDir).forEach((filename) => {
if (filename.endsWith('.js')) {
const routeFactory = require(path.join(routesDir, filename));
routeFactory(server);
}
});
}
DatabaseConnector.forShared().then(({Account}) => {
server.register([HapiWebSocket, Inert], () => {
attach('./routes/')
server.route({
method: "POST",
path: "/accounts",

View file

@ -47,3 +47,16 @@ pre {
width: inherit;
overflow: hidden;
}
.sync-policy .action-link {
display: inline-block;
margin: 5px;
color: rgba(16, 83, 161, 0.88);
text-decoration: underline;
cursor: pointer;
}
.sync-policy textarea {
width: 100%;
height: 200px;
}

View file

@ -3,6 +3,7 @@
<script src="/js/react.js"></script>
<script src="/js/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="/js/sync-policy.jsx" type="text/babel"></script>
<script src="/js/app.jsx" type="text/babel"></script>
<link rel='stylesheet' type="text/css" href="./css/app.css" />
<link rel='shortcut icon' href='favicon.png' / >

View file

@ -1,6 +1,7 @@
/* eslint react/react-in-jsx-scope: 0*/
const React = window.React;
const ReactDOM = window.ReactDOM;
const SyncPolicy = window.SyncPolicy;
class Account extends React.Component {
renderError() {
@ -36,8 +37,10 @@ class Account extends React.Component {
<div className={`account${errorClass}`}>
<h3>{account.email_address} {active ? '🌕' : '🌑'}</h3>
<strong>{assignment}</strong>
<div className="section">Sync Policy</div>
<pre>{JSON.stringify(account.sync_policy, null, 2)}</pre>
<SyncPolicy
accountId={account.id}
stringifiedSyncPolicy={JSON.stringify(account.sync_policy, null, 2)}
/>
<div className="section">Sync Cycles</div>
<div>
<b>First Sync Completion</b>:

View file

@ -0,0 +1,66 @@
const React = window.React;
class SyncPolicy extends React.Component {
constructor(props) {
super(props);
this.state = {editMode: false};
this.accountId = props.accountId;
}
edit() {
this.setState({editMode: true})
}
save() {
const req = new XMLHttpRequest();
const url = `${window.location.protocol}/sync-policy/${this.accountId}`;
req.open("POST", url, true);
req.setRequestHeader("Content-type", "application/json");
req.onreadystatechange = () => {
if (req.readyState === XMLHttpRequest.DONE) {
console.log(req.responseText);
if (req.status === 200) {
this.setState({editMode: false});
}
}
}
const newPolicy = document.getElementById(`sync-policy-${this.accountId}`).value;
req.send(JSON.stringify({sync_policy: newPolicy}));
}
cancel() {
this.setState({editMode: false});
}
render() {
if (this.state.editMode) {
const id = `sync-policy-${this.props.accountId}`;
return (
<div className="sync-policy">
<div className="section">Sync Policy</div>
<textarea id={id}>
{this.props.stringifiedSyncPolicy}
</textarea>
<button onClick={() => this.save.call(this)}> Save </button>
<span className="action-link" onClick={() => this.cancel.call(this)}> Cancel </span>
</div>
)
}
return (
<div className="sync-policy">
<div className="section">Sync Policy</div>
<pre>{this.props.stringifiedSyncPolicy}</pre>
<span className="action-link" onClick={() => this.edit.call(this)}> Edit </span>
</div>
)
}
}
SyncPolicy.propTypes = {
accountId: React.PropTypes.number,
stringifiedSyncPolicy: React.PropTypes.string,
}
window.SyncPolicy = SyncPolicy;

View file

@ -0,0 +1,30 @@
const Joi = require('joi');
const {SchedulerUtils} = require(`nylas-core`);
module.exports = (server) => {
server.route({
method: 'POST',
path: '/sync-policy/{account_id}',
config: {
description: 'Set the sync policy',
notes: 'Notes go here',
tags: ['sync-policy'],
validate: {
params: {
account_id: Joi.number().integer(),
},
payload: {
sync_policy: Joi.string(),
},
},
response: {
schema: Joi.string(),
},
},
handler: (request, reply) => {
const newPolicy = JSON.parse(request.payload.sync_policy);
SchedulerUtils.assignPolicy(request.params.account_id, newPolicy)
.then(() => reply("Success"));
},
});
};