UI tweaks, get JSXTransformer out.

This commit is contained in:
Adam Ierymenko 2015-05-08 09:39:07 -07:00
parent 4426899e8c
commit a4a62be698
5 changed files with 78 additions and 1869 deletions

1820
ui/JSXTransformer.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,6 @@
var ZeroTierNetwork = React.createClass({ var ZeroTierNetwork = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {};
deleted: false
};
}, },
leaveNetwork: function(event) { leaveNetwork: function(event) {
@ -11,7 +9,8 @@ var ZeroTierNetwork = React.createClass({
cache: false, cache: false,
type: 'DELETE', type: 'DELETE',
success: function(data) { success: function(data) {
this.setState({deleted: true}); if (this.props.onNetworkDeleted)
this.props.onNetworkDeleted(this.props.nwid);
}.bind(this), }.bind(this),
error: function(error) { error: function(error) {
}.bind(this) }.bind(this)
@ -22,13 +21,8 @@ var ZeroTierNetwork = React.createClass({
render: function() { render: function() {
return ( return (
<div className="zeroTierNetwork"> <div className="zeroTierNetwork">
{
(this.state.deleted) ? (
<div className="deletedOverlay">&nbsp;</div>
) : (null)
}
<div className="networkInfo"> <div className="networkInfo">
<span className="networkId">{this.props.nwid}</span> <span className="networkId">{this.props.nwid}</span>&nbsp;
<span className="networkName">{this.props.name}</span> <span className="networkName">{this.props.name}</span>
</div> </div>
<div className="networkProps"> <div className="networkProps">

View file

@ -56,6 +56,7 @@ var ZeroTierNode = React.createClass({
cache: false, cache: false,
type: 'GET', type: 'GET',
success: function(data) { success: function(data) {
this.alertedToFailure = false;
if (data) { if (data) {
var status = JSON.parse(data); var status = JSON.parse(data);
this.setState(status); this.setState(status);
@ -65,7 +66,11 @@ var ZeroTierNode = React.createClass({
this.updatePeers(); this.updatePeers();
}.bind(this), }.bind(this),
error: function() { error: function() {
this.setState({online: false}); this.setState(this.getInitialState());
if (!this.alertedToFailure) {
this.alertedToFailure = true;
alert('Authorization token invalid or ZeroTier One service not running.');
}
}.bind(this) }.bind(this)
}); });
}, },
@ -77,13 +82,20 @@ var ZeroTierNode = React.createClass({
cache: false, cache: false,
type: 'POST', type: 'POST',
success: function(data) { success: function(data) {
this.networkToJoin = '';
if (this.networkInputElement)
this.networkInputElement.value = '';
this.updateNetworks();
}.bind(this), }.bind(this),
error: function() { error: function() {
}.bind(this) }.bind(this)
}); });
} else {
alert('To join a network, enter its 16-digit network ID.');
} }
}, },
handleNetworkIdEntry: function(event) { handleNetworkIdEntry: function(event) {
this.networkInputElement = event.target;
var nid = event.target.value; var nid = event.target.value;
if (nid) { if (nid) {
nid = nid.toLowerCase(); nid = nid.toLowerCase();
@ -100,6 +112,15 @@ var ZeroTierNode = React.createClass({
} }
}, },
handleNetworkDelete: function(nwid) {
var networks = [];
for(var i=0;i<this.state._networks.length;++i) {
if (this.state._networks[i].nwid !== nwid)
networks.push(this.state._networks[i]);
}
this.setState({_networks: networks});
},
componentDidMount: function() { componentDidMount: function() {
this.tabIndex = 0; this.tabIndex = 0;
this.updateAll(); this.updateAll();
@ -109,11 +130,15 @@ var ZeroTierNode = React.createClass({
clearInterval(this.updateIntervalId); clearInterval(this.updateIntervalId);
}, },
render: function() { render: function() {
/* We implement tabs in a very simple way here with a React JSX conditional. The tabIndex
* local variable indicates the tab, and switching it determines which set of things we
* render in the main middle portion. On tab switch calls forceUpdate(). */
return ( return (
<div className="zeroTierNode"> <div className="zeroTierNode">
<div className="top">&nbsp;&nbsp; <div className="top">&nbsp;&nbsp;
<button disabled={this.tabIndex === 0} onClick={function() {this.tabIndex = 0; this.forceUpdate();}.bind(this)}>Networks</button> <button disabled={this.tabIndex === 0} onClick={function() {this.tabIndex = 0; this.forceUpdate();}.bind(this)}>Networks</button>
<button disabled={this.tabIndex === 1} onClick={function() {this.tabIndex = 1; this.forceUpdate();}.bind(this)}>Peers</button> <button disabled={this.tabIndex === 1} onClick={function() {this.tabIndex = 1; this.forceUpdate();}.bind(this)}>Peers</button>
<div className="logo">&#x23c1;&nbsp;</div>
</div> </div>
<div className="middle"> <div className="middle">
<div className="middleScroll"> <div className="middleScroll">
@ -124,7 +149,8 @@ var ZeroTierNode = React.createClass({
<div className="f">Address</div> <div className="f">Address</div>
<div className="f">Version</div> <div className="f">Version</div>
<div className="f">Latency</div> <div className="f">Latency</div>
<div className="f">Direct&nbsp;Paths</div> <div className="f">Data&nbsp;Paths</div>
<div className="f">Last&nbsp;Frame</div>
<div className="f">Role</div> <div className="f">Role</div>
</div> </div>
{ {
@ -137,26 +163,22 @@ var ZeroTierNode = React.createClass({
<div className="f"> <div className="f">
{ {
(peer['paths'].length === 0) ? ( (peer['paths'].length === 0) ? (
<div className="peerPath"><i>(none)</i></div> <div className="peerPath"></div>
) : ( ) : (
<div> <div>
{ {
peer['paths'].map(function(path) { peer['paths'].map(function(path) {
if ((path.active)||(path.fixed)) { var cn = ((path.active)||(path.fixed)) ? (path.preferred ? 'peerPathPreferred' : 'peerPathActive') : 'peerPathInactive';
return ( return (
<div className="peerPath">{path.address}&nbsp;{this.ago(path.lastSend)}&nbsp;{this.ago(path.lastReceive)}{path.preferred ? ' *' : ''}</div> <div className={cn}>{path.address}&nbsp;&nbsp;{this.ago(path.lastSend)}/{this.ago(path.lastReceive)}</div>
); );
} else {
return (
<div className="peerPathInactive">{path.address}&nbsp;{this.ago(path.lastSend)}&nbsp;{this.ago(path.lastReceive)}</div>
);
}
}.bind(this)) }.bind(this))
} }
</div> </div>
) )
} }
</div> </div>
<div className="f">{this.ago(peer['lastUnicastFrame'])}</div>
<div className="f">{peer['role']}</div> <div className="f">{peer['role']}</div>
</div> </div>
); );
@ -168,6 +190,7 @@ var ZeroTierNode = React.createClass({
{ {
this.state._networks.map(function(network) { this.state._networks.map(function(network) {
network['authToken'] = this.props.authToken; network['authToken'] = this.props.authToken;
network['onNetworkDeleted'] = this.handleNetworkDelete;
return React.createElement('div',{className: 'network'},React.createElement(ZeroTierNetwork,network)); return React.createElement('div',{className: 'network'},React.createElement(ZeroTierNetwork,network));
}.bind(this)) }.bind(this))
} }
@ -181,7 +204,7 @@ var ZeroTierNode = React.createClass({
<span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span>&nbsp;&nbsp;{this.state.online ? 'ONLINE' : 'OFFLINE'}&nbsp;&nbsp;{this.state.version}</span> <span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span>&nbsp;&nbsp;{this.state.online ? 'ONLINE' : 'OFFLINE'}&nbsp;&nbsp;{this.state.version}</span>
</div> </div>
<div className="right"> <div className="right">
<form onSubmit={this.joinNetwork}><input type="text" placeholder="################" onChange={this.handleNetworkIdEntry} size="16"/><button type="submit">Join</button></form> <form onSubmit={this.joinNetwork}><input type="text" placeholder=" [ Network ID ]" onChange={this.handleNetworkIdEntry} size="16"/><button type="submit">Join</button></form>
</div> </div>
</div> </div>
</div> </div>

View file

@ -12,12 +12,11 @@
<script src="simpleajax.min.js"></script> <script src="simpleajax.min.js"></script>
<script src="react.min.js"></script> <script src="react.min.js"></script>
<script src="JSXTransformer.min.js"></script>
<script type="text/jsx" src="ZeroTierNetwork.jsx"></script> <script src="ZeroTierNetwork.js"></script>
<script type="text/jsx" src="ZeroTierNode.jsx"></script> <script src="ZeroTierNode.js"></script>
<script type="text/jsx" src="main.jsx"></script> <script src="main.js"></script>
</head> </head>
<body> <body>
<div style="width: 100%; height: 100%;" id="main"></div> <div style="width: 100%; height: 100%;" id="main"></div>

View file

@ -36,6 +36,14 @@ html,body {
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
.zeroTierNode > .top > .logo {
display: inline-block;
padding: 0.1em 0 0 0;
margin: 0;
font-size: 12pt;
font-weight: bold;
float: right;
}
.zeroTierNode > .top button { .zeroTierNode > .top button {
display: inline-block; display: inline-block;
padding: 0.25rem 0.75rem 0.25rem 0.75rem; padding: 0.25rem 0.75rem 0.25rem 0.75rem;
@ -70,7 +78,7 @@ html,body {
margin: 0; margin: 0;
overflow-x: hidden; overflow-x: hidden;
overflow-y: scroll; overflow-y: scroll;
background: #eeeeee; background: #dddddd;
} }
.zeroTierNode > .middle > .middleScroll > .networks { .zeroTierNode > .middle > .middleScroll > .networks {
display: block; display: block;
@ -81,17 +89,17 @@ html,body {
border-collapse: collapse; border-collapse: collapse;
} }
.zeroTierNode > .middle > .middleScroll > .networks > .network { .zeroTierNode > .middle > .middleScroll > .networks > .network {
padding: 0.5rem; padding: 0.25rem;
margin: 0.25rem; margin: 0.25rem 0 0 0.25rem;
float: left; float: left;
display: inline-block; display: inline-block;
min-width: 30%;
border: 1px solid #234447; border: 1px solid #234447;
background: #ffffff; background: #ffffff;
} }
.zeroTierNode > .middle > .middleScroll > .peers { .zeroTierNode > .middle > .middleScroll > .peers {
display: table; display: table;
width: 100%; width: 100%;
padding: 0;
margin: 0; margin: 0;
border-collapse: collapse; border-collapse: collapse;
} }
@ -100,20 +108,35 @@ html,body {
display: table-row; display: table-row;
background: #ffffff; background: #ffffff;
} }
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPath { .zeroTierNode > .middle > .middleScroll > .peers > .peer:nth-child(odd) {
background: #f3f3f3;
}
.zeroTierNode > .middle > .middleScroll > .peers > .peer:nth-child(even) {
}
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathActive {
font-size: 10pt; font-size: 10pt;
color: #555555;
font-style: italic;
font-family: monospace;
white-space: nowrap;
}
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathPreferred {
font-size: 10pt;
color: #000000;
font-family: monospace; font-family: monospace;
white-space: nowrap; white-space: nowrap;
} }
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathInactive { .zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathInactive {
font-size: 10pt; font-size: 10pt;
font-family: monospace; font-family: monospace;
color: #bbbbbb; color: #aaaaaa;
font-style: italic;
text-decoration: line-through; text-decoration: line-through;
white-space: nowrap; white-space: nowrap;
} }
.zeroTierNode > .middle > .middleScroll > .peers > .peer > .f { .zeroTierNode > .middle > .middleScroll > .peers > .peer > .f {
display: table-cell; display: table-cell;
padding: 0.05rem 0.15rem 0.05rem 0.15rem;
font-size: 10pt; font-size: 10pt;
} }
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader { .zeroTierNode > .middle > .middleScroll > .peers > .peerHeader {
@ -125,6 +148,7 @@ html,body {
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader > .f { .zeroTierNode > .middle > .middleScroll > .peers > .peerHeader > .f {
display: table-cell; display: table-cell;
font-size: 10pt; font-size: 10pt;
padding: 0.05rem 0.15rem 0.05rem 0.15rem;
font-weight: bold; font-weight: bold;
} }
@ -155,13 +179,12 @@ html,body {
.zeroTierNode > .bottom > .right input { .zeroTierNode > .bottom > .right input {
font-family: monospace; font-family: monospace;
font-size: 12pt; font-size: 12pt;
background: #91a2a3; background: #ffffff;
color: #ffffff; color: #000000;
outline: none; outline: none;
border: 0; border: 1px solid #234447;
margin: 0; margin: 0;
padding: 0.05rem 0.25rem 0.05rem 0.25rem; padding: 0.05rem 0.25rem 0.05rem 0.25rem;
height: 100%;
display: inline-block; display: inline-block;
} }
.zeroTierNode > .bottom > .right button { .zeroTierNode > .bottom > .right button {
@ -187,18 +210,8 @@ html,body {
width: 100%; width: 100%;
position: relative; position: relative;
} }
.zeroTierNetwork .deletedOverlay {
width: 100%;
height: 100%;
position: absolute;
background: rgba(255,255,255,0.8);
display: block;
top: 0;
left: 0;
z-index: 2;
}
.zeroTierNetwork .networkInfo { .zeroTierNetwork .networkInfo {
padding: 0 0 0.5rem 0; padding: 0 0 0.25rem 0;
text-align: left; text-align: left;
font-size: 12pt; font-size: 12pt;
} }
@ -242,7 +255,7 @@ html,body {
} }
.zeroTierNetwork .leaveNetworkButton { .zeroTierNetwork .leaveNetworkButton {
padding: 0.25rem 0.5rem 0.25rem 0.5rem; padding: 0.25rem 0.5rem 0.25rem 0.5rem;
margin: 0.5rem 0 0 0; margin: 0.25rem 0 0 0;
font-size: 10pt; font-size: 10pt;
background: #ffffff; background: #ffffff;
outline: none; outline: none;