Settings UI for multiple teams with React

This commit is contained in:
Yuya Ochiai
2015-12-19 23:51:19 +09:00
parent 05d397549b
commit 283e311095
5 changed files with 132 additions and 31 deletions

View File

@@ -5,7 +5,10 @@ const version = 1;
var upgradeV0toV1 = function(config_v0) {
return {
url: [config_v0.url],
teams: [{
name: 'Primary team',
url: config_v0.url
}],
version: 1
};
};

View File

@@ -19,8 +19,8 @@ try {
config = settings.upgrade(config);
settings.writeFileSync(configFile, config);
}
if (config.url[0]) {
webView.setAttribute('src', config.url[0]);
if (config.teams[0]) {
webView.setAttribute('src', config.teams[0].url);
}
else {
throw 'URL is not configured';

View File

@@ -4,35 +4,13 @@
<head>
<meta charset="UTF-8">
<title>Settings</title>
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
</head>
<body>
<h1>Settings</h1>
<p>URL:
<input type="text" id="url">
</p>
<input type="button" value="OK" onclick="saveSettings()">
<input type="button" value="Cancel" onclick="goBack()">
<script type="text/javascript">
const remote = require('electron').remote;
const settings = require('./common/settings');
var saveSettings = function() {
var configFile = remote.getGlobal('config-file');
var urlInput = document.getElementById('url');
var config = {
url: [urlInput.value],
version: 1
};
settings.writeFileSync(configFile, config);
window.location.href = './index.html';
}
var goBack = function() {
remote.getCurrentWindow().webContents.goBack();
}
</script>
<div id="content"></div>
<script src="build/settings.js"></script>
</body>
</html>

120
src/settings.jsx Normal file
View File

@@ -0,0 +1,120 @@
'use strict';
const remote = require('electron').remote;
const settings = require('./common/settings');
var SettingsPage = React.createClass({
getInitialState: function() {
return {
teams: []
};
},
componentDidMount: function() {
var config = settings.readFileSync(this.props.configFile);
this.setState({teams: config.teams})
},
handleTeamsChange: function(teams) {
this.setState({teams: teams});
},
handleOK: function() {
var config = {
teams: this.state.teams,
version: 1
};
settings.writeFileSync(this.props.configFile, config);
window.location = './index.html';
},
handleCancel: function() {
window.location = './index.html';
},
render: function() {
return (
<div className="settingsPage">
<TeamList teams={this.state.teams} onTeamsChange={this.handleTeamsChange} />
<input type="button" value="OK" onClick={this.handleOK} />
<input type="button" value="Cancel" onClick={this.handleCancel} />
</div>
);
}
});
var TeamList = React.createClass({
handleTeamChange: function(index, team){
var teams = this.props.teams;
teams[index] = team;
this.props.onTeamsChange(teams);
},
handleNewTeamAdd: function(team){
var teams = this.props.teams;
teams.push(team);
this.props.onTeamsChange(teams);
},
render: function() {
var thisObj = this;
var teamNodes = this.props.teams.map(function(team, i){
var handleTeamChange = function(team){
thisObj.handleTeamChange(i, team);
};
return (
<li><TeamItem index={i} name={team.name} url={team.url} onTeamChange={handleTeamChange} onName /></li>
);
});
return (
<div className="teamList">
<ol>
{teamNodes}
<li><NewTeamItem onNewTeamAdd={this.handleNewTeamAdd} /></li>
</ol>
</div>
);
}
});
var TeamItem = React.createClass({
handleNameChange: function(e){
this.props.onTeamChange({name: e.target.value, url: this.props.url});
},
handleURLChange: function(e){
this.props.onTeamChange({name: this.props.name, url: e.target.value});
},
render: function() {
return (
<div className="teamItem">
<input type="text" placeholder="Team name" value={this.props.name} onChange={this.handleNameChange} ></input>
<input type="text" placeholder="Team URL (http://example.com/team)" value={this.props.url} onChange={this.handleURLChange} ></input>
</div>
);
}
});
var NewTeamItem = React.createClass({
getInitialState: function(){
return {name: '', url: ''};
},
handleNewTeamAdd: function(){
this.props.onNewTeamAdd({name: this.state.name, url: this.state.url});
this.setState(this.getInitialState());
},
handleNameChange: function(e){
this.setState({name: e.target.value});
},
handleURLChange: function(e){
this.setState({url: e.target.value});
},
render: function() {
return (
<div className="newTeamItem">
<input type="text" placeholder="Team name" value={this.state.name} onChange={this.handleNameChange} />
<input type="text" placeholder="Team URL (http://example.com/team)" value={this.state.url} onChange={this.handleURLChange} />
<input type="button" value="Add" onClick={this.handleNewTeamAdd} />
</div>
);
}
});
var configFile = remote.getGlobal('config-file');
ReactDOM.render(
<SettingsPage configFile={configFile} />,
document.getElementById('content')
);

View File

@@ -11,8 +11,8 @@ describe('settings.js', function() {
url: 'http://example.com/team'
};
config = settings.upgrade(v0_config);
config.url.length.should.equal(1);
config.url[0].should.equal(v0_config.url);
config.teams.length.should.equal(1);
config.teams[0].url.should.equal(v0_config.url);
config.version.should.equal(settings.version);
});
});