Merge pull request #295 from influxdata/feature/216-add-edit-sources

Add / Edit Sources
pull/313/head
Will Piers 2016-10-31 10:45:02 -07:00 committed by GitHub
commit 2a79591556
6 changed files with 161 additions and 12 deletions

View File

@ -1,6 +1,6 @@
import React, {PropTypes} from 'react';
import {withRouter} from 'react-router';
import {getSources} from 'src/shared/apis';
import {getSources} from 'shared/apis';
const {bool, number, string, node, func, shape} = PropTypes;

View File

@ -13,7 +13,7 @@ import RetentionPoliciesPage from 'src/retention_policies';
import DataExplorer from 'src/chronograf';
import DatabaseManager from 'src/database_manager';
import SignUp from 'src/sign_up';
import {CreateSource, ManageSources} from 'src/sources';
import {CreateSource, SourceForm, ManageSources} from 'src/sources';
import {ClusterAccountsPage, ClusterAccountPage} from 'src/cluster_accounts';
import {RolesPageContainer, RolePageContainer} from 'src/access_control';
import NotFound from 'src/shared/components/NotFound';
@ -100,6 +100,8 @@ const Root = React.createClass({
<Route path="/sources/:sourceID" component={App}>
<Route component={CheckDataNodes}>
<Route path="manage-sources" component={ManageSources} />
<Route path="manage-sources/new" component={SourceForm} />
<Route path="manage-sources/:id/edit" component={SourceForm} />
<Route path="queries" component={QueriesPage} />
<Route path="accounts" component={ClusterAccountsPage} />
<Route path="accounts/:accountID" component={ClusterAccountPage} />

View File

@ -6,17 +6,25 @@ export function getSources() {
});
}
export function createSource({url, name, username, password, isDefault}) {
export function getSource(sourceID) {
return AJAX({
url: `/chronograf/v1/sources/${sourceID}`,
});
}
export function createSource(attributes) {
return AJAX({
url: '/chronograf/v1/sources',
method: 'POST',
data: {
url,
name,
username,
password,
'default': isDefault,
},
data: attributes,
});
}
export function updateSource(newSource) {
return AJAX({
url: newSource.links.self,
method: 'PATCH',
data: newSource,
});
}

View File

@ -81,7 +81,7 @@ export const ManageSources = React.createClass({
}
</tbody>
</table>
<div className="btn btn-primary">Add</div>
<Link to={`/sources/1/manage-sources/new`} className="btn btn-primary">Add</Link>
</div>
</div>
</div>

View File

@ -0,0 +1,138 @@
import React, {PropTypes} from 'react';
import {withRouter} from 'react-router';
import {getSource, createSource, updateSource} from 'shared/apis';
export const SourceForm = React.createClass({
propTypes: {
params: PropTypes.shape({
id: PropTypes.string,
}),
router: PropTypes.shape({
push: PropTypes.func.isRequired,
}).isRequired,
location: PropTypes.shape({
query: PropTypes.shape({
redirectPath: PropTypes.string,
}).isRequired,
}).isRequired,
addFlashMessage: PropTypes.func.isRequired,
},
getInitialState() {
return {
source: {},
editMode: this.props.params.id !== undefined,
};
},
componentDidMount() {
if (!this.state.editMode) {
return;
}
getSource(this.props.params.id).then(({data: source}) => {
this.setState({source});
});
},
handleSubmit(e) {
e.preventDefault();
const {router, params, addFlashMessage} = this.props;
const newSource = Object.assign({}, this.state.source, {
url: this.sourceURL.value,
name: this.sourceName.value,
username: this.sourceUsername.value,
password: this.sourcePassword.value,
'default': this.sourceDefault.checked,
});
if (this.state.editMode) {
updateSource(newSource).then(() => {
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully updated'});
});
} else {
createSource(newSource).then(() => {
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully created'});
});
}
},
onInputChange(e) {
const val = e.target.value;
const name = e.target.name;
this.setState((prevState) => {
const newSource = Object.assign({}, prevState.source, {
[name]: val,
});
return Object.assign({}, prevState, {source: newSource});
});
},
render() {
const {source, editMode} = this.state;
if (editMode && !source.id) {
return <div className="page-spinner"></div>;
}
return (
<div id="source-form-page">
<div className="enterprise-header">
<div className="enterprise-header__container">
<div className="enterprise-header__left">
<h1>
Source Form
</h1>
</div>
</div>
</div>
<div className="container">
<div className="row">
<div className="col-md-8 col-md-offset-2">
<div className="panel panel-summer">
<div className="panel-body">
<h4 className="text-center">{editMode ? "Update Existing Source" : "Connect to a New Source"}</h4>
<br/>
<form onSubmit={this.handleSubmit}>
<div>
<div className="form-group col-xs-6 col-sm-4 col-sm-offset-2">
<label htmlFor="connect-string">Connection String</label>
<input type="text" name="url" ref={(r) => this.sourceURL = r} className="form-control" id="connect-string" placeholder="http://localhost:8086" onChange={this.onInputChange} value={source.url || ''}></input>
</div>
<div className="form-group col-xs-6 col-sm-4">
<label htmlFor="name">Name</label>
<input type="text" name="name" ref={(r) => this.sourceName = r} className="form-control" id="name" placeholder="Influx 1" onChange={this.onInputChange} value={source.name || ''}></input>
</div>
<div className="form-group col-xs-6 col-sm-4 col-sm-offset-2">
<label htmlFor="username">Username</label>
<input type="text" name="username" ref={(r) => this.sourceUsername = r} className="form-control" id="username" onChange={this.onInputChange} value={source.username || ''}></input>
</div>
<div className="form-group col-xs-6 col-sm-4">
<label htmlFor="password">Password</label>
<input type="password" name="password" ref={(r) => this.sourcePassword = r} className="form-control" id="password" onChange={this.onInputChange} value={source.password || ''}></input>
</div>
<div className="form-group col-xs-6 col-xs-offset-2">
<div className="checkbox">
<label>
<input type="checkbox" defaultChecked={source.default} ref={(r) => this.sourceDefault = r} />
Default source
</label>
</div>
</div>
</div>
<div className="form-group col-xs-12 text-center">
<button className="btn btn-success" type="submit">{editMode ? "Update" : "Create"}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
},
});
export default withRouter(SourceForm);

View File

@ -1,3 +1,4 @@
import CreateSource from './containers/CreateSource';
import SourceForm from './containers/SourceForm';
import ManageSources from './containers/ManageSources';
export {CreateSource, ManageSources};
export {CreateSource, SourceForm, ManageSources};