Merge pull request #295 from influxdata/feature/216-add-edit-sources
Add / Edit Sourcespull/313/head
commit
2a79591556
|
@ -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;
|
||||
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
|
@ -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};
|
||||
|
|
Loading…
Reference in New Issue