From b3dbbcfcef4af5d6ac4910c90e5b8715e91c0505 Mon Sep 17 00:00:00 2001 From: Will Piers Date: Tue, 11 Oct 2016 17:21:49 -0700 Subject: [PATCH 1/3] Set up route and initial html for managing sources --- ui/src/index.js | 45 +------------ ui/src/select_source/index.js | 2 - ui/src/side_nav/components/SideNav.js | 2 +- ui/src/sources/containers/ManageSources.js | 63 +++++++++++++++++++ .../containers/SelectSourcePage.js | 0 ui/src/sources/index.js | 3 + 6 files changed, 69 insertions(+), 46 deletions(-) delete mode 100644 ui/src/select_source/index.js create mode 100644 ui/src/sources/containers/ManageSources.js rename ui/src/{select_source => sources}/containers/SelectSourcePage.js (100%) create mode 100644 ui/src/sources/index.js diff --git a/ui/src/index.js b/ui/src/index.js index 648bddedb6..6a913e2753 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -12,7 +12,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 SelectSourcePage from 'src/select_source'; +import {SelectSourcePage, 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'; @@ -48,47 +48,6 @@ const Root = React.createClass({ }; }, - componentDidMount() { - // meShow().then(({data: me}) => { - // const match = window.location.pathname.match(/\/clusters\/(\d*)/); - // const clusterID = match && match[1]; - // const clusterLink = me.cluster_links.find(link => link.cluster_id === clusterID); - // if (clusterLink) { - // Promise.all([ - // getClusterAccount(clusterID, clusterLink.cluster_user), - // getRoles(clusterID), - // ]).then(([{data: {users}}, {data: {roles}}]) => { - // const account = buildClusterAccounts(users, roles)[0]; - // const canViewChronograf = hasPermission(account, VIEW_CHRONOGRAF); - // const hasReadPermission = hasPermission(account, READ); - // this.setState({ - // me, - // canViewChronograf, - // isFetching: false, - // hasReadPermission, - // }); - // }).catch((err) => { - // console.error(err); // eslint-disable-line no-console - // this.setState({ - // canViewChronograf: false, - // isFetching: false, - // clusterStatus: err.response.status, - // }); - // }); - // } else { - // this.setState({ - // me, - // isFetching: false, - // }); - // } - // }).catch((err) => { - // console.error(err); // eslint-disable-line no-console - // this.setState({ - // isFetching: false, - // }); - // }); - }, - childContextTypes: { me: shape({ id: number.isRequired, @@ -125,9 +84,9 @@ const Root = React.createClass({ - + diff --git a/ui/src/select_source/index.js b/ui/src/select_source/index.js deleted file mode 100644 index a172a2b31e..0000000000 --- a/ui/src/select_source/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import SelectSourcePage from './containers/SelectSourcePage'; -export default SelectSourcePage; diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index 3d83299d0b..35f019ac7f 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -27,7 +27,7 @@ const SideNav = React.createClass({ - Manage Sources + Manage Sources Queries Tasks Roles diff --git a/ui/src/sources/containers/ManageSources.js b/ui/src/sources/containers/ManageSources.js new file mode 100644 index 0000000000..f6aec7b71b --- /dev/null +++ b/ui/src/sources/containers/ManageSources.js @@ -0,0 +1,63 @@ +import React, {PropTypes} from 'react'; +import {withRouter} from 'react-router'; +import FlashMessages from 'shared/components/FlashMessages'; +import {getSources} from 'shared/apis'; + +export const ManageSources = React.createClass({ + propTypes: { + }, + + getInitialState() { + return { + sources: [], + }; + }, + + componentDidMount() { + getSources().then(({data: {sources}}) => { + this.setState({sources}); + }); + }, + + changeSort() {}, + + render() { + const {sources} = this.state; + return ( +
+
+
+
+ + + + + + + + + + + { + sources.map((source) => { + return ( + + + + + + + ); + }) + } + +
NameHostKapacitorDefault
{source.name}{source.url}{source.links.kapacitors}
+
+
+
+
+ ); + }, +}); + +export default FlashMessages(withRouter(ManageSources)); diff --git a/ui/src/select_source/containers/SelectSourcePage.js b/ui/src/sources/containers/SelectSourcePage.js similarity index 100% rename from ui/src/select_source/containers/SelectSourcePage.js rename to ui/src/sources/containers/SelectSourcePage.js diff --git a/ui/src/sources/index.js b/ui/src/sources/index.js new file mode 100644 index 0000000000..e83c52fac1 --- /dev/null +++ b/ui/src/sources/index.js @@ -0,0 +1,3 @@ +import SelectSourcePage from './containers/SelectSourcePage'; +import ManageSources from './containers/ManageSources'; +export {SelectSourcePage, ManageSources}; From b4c3ec5977e5d5d3cbc7fb7916e34ecc709a42a4 Mon Sep 17 00:00:00 2001 From: Will Piers Date: Wed, 12 Oct 2016 14:10:45 -0700 Subject: [PATCH 2/3] Refactor how default source works and second pass on manage source page --- ui/src/index.js | 21 ++++++++----- ui/src/shared/apis/index.js | 3 +- .../{SelectSourcePage.js => CreateSource.js} | 6 ++-- ui/src/sources/containers/ManageSources.js | 31 ++++++++++++++----- ui/src/sources/index.js | 4 +-- 5 files changed, 44 insertions(+), 21 deletions(-) rename ui/src/sources/containers/{SelectSourcePage.js => CreateSource.js} (94%) diff --git a/ui/src/index.js b/ui/src/index.js index 6a913e2753..f624fa9d75 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -12,12 +12,13 @@ import RetentionPoliciesPage from 'src/retention_policies'; import DataExplorer from 'src/chronograf'; import DatabaseManager from 'src/database_manager'; import SignUp from 'src/sign_up'; -import {SelectSourcePage, ManageSources} from 'src/sources'; +import {CreateSource, 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'; import NoClusterError from 'src/shared/components/NoClusterError'; import configureStore from 'src/store/configureStore'; +import {getSources} from 'shared/apis'; import 'src/style/enterprise_style/application.scss'; @@ -63,11 +64,17 @@ const Root = React.createClass({ }; }, - hasDefaultSource(_, replace) { - const defaultSource = JSON.parse(localStorage.getItem('defaultSource')); - if (!!defaultSource && defaultSource.id) { - return replace(`/sources/${defaultSource.id}/hosts`); - } + hasSources(_, replace, callback) { + getSources().then(({data: {sources}}) => { + if (sources && sources.length) { + const defaultSource = sources.find((s) => s.default); + if (defaultSource && defaultSource.id) { + replace(`/sources/${defaultSource.id}/hosts`); + } + replace(`/sources/${sources[0].id}/hosts`); + } + callback(); + }).catch(callback); }, render() { @@ -83,7 +90,7 @@ const Root = React.createClass({ - + diff --git a/ui/src/shared/apis/index.js b/ui/src/shared/apis/index.js index 0ae16a222a..57dc38f151 100644 --- a/ui/src/shared/apis/index.js +++ b/ui/src/shared/apis/index.js @@ -6,7 +6,7 @@ export function getSources() { }); } -export function createSource({url, name, username, password}) { +export function createSource({url, name, username, password, isDefault}) { return AJAX({ url: '/chronograf/v1/sources', method: 'POST', @@ -15,6 +15,7 @@ export function createSource({url, name, username, password}) { name, username, password, + 'default': isDefault, }, }); } diff --git a/ui/src/sources/containers/SelectSourcePage.js b/ui/src/sources/containers/CreateSource.js similarity index 94% rename from ui/src/sources/containers/SelectSourcePage.js rename to ui/src/sources/containers/CreateSource.js index 7489d15d3b..7f4e51a353 100644 --- a/ui/src/sources/containers/SelectSourcePage.js +++ b/ui/src/sources/containers/CreateSource.js @@ -3,7 +3,7 @@ import {withRouter} from 'react-router'; import FlashMessages from 'shared/components/FlashMessages'; import {createSource} from 'shared/apis'; -export const SelectSourcePage = React.createClass({ +export const CreateSource = React.createClass({ propTypes: { router: PropTypes.shape({ push: PropTypes.func.isRequired, @@ -22,9 +22,9 @@ export const SelectSourcePage = React.createClass({ name: this.sourceName.value, username: this.sourceUser.value, password: this.sourcePassword.value, + isDefault: true, }; createSource(source).then(({data: sourceFromServer}) => { - localStorage.setItem('defaultSource', JSON.stringify(sourceFromServer)); this.redirectToApp(sourceFromServer); }); }, @@ -87,4 +87,4 @@ export const SelectSourcePage = React.createClass({ }, }); -export default FlashMessages(withRouter(SelectSourcePage)); +export default FlashMessages(withRouter(CreateSource)); diff --git a/ui/src/sources/containers/ManageSources.js b/ui/src/sources/containers/ManageSources.js index f6aec7b71b..7880aaf4e2 100644 --- a/ui/src/sources/containers/ManageSources.js +++ b/ui/src/sources/containers/ManageSources.js @@ -1,12 +1,14 @@ import React, {PropTypes} from 'react'; -import {withRouter} from 'react-router'; +import {withRouter, Link} from 'react-router'; import FlashMessages from 'shared/components/FlashMessages'; import {getSources} from 'shared/apis'; export const ManageSources = React.createClass({ propTypes: { + location: PropTypes.shape({ + pathname: PropTypes.string.isRequired, + }).isRequired, }, - getInitialState() { return { sources: [], @@ -23,8 +25,19 @@ export const ManageSources = React.createClass({ render() { const {sources} = this.state; + const {pathname} = this.props.location; + return ( -
+
+
+
+
+

+ Manage Sources +

+
+
+
@@ -34,7 +47,7 @@ export const ManageSources = React.createClass({ Name Host Kapacitor - Default + @@ -42,16 +55,18 @@ export const ManageSources = React.createClass({ sources.map((source) => { return ( - {source.name} - {source.url} - {source.links.kapacitors} - + {source.name}{source.default ? Default : null} + {source.url} + {source.links.kapacitors} + Edit ); }) } +
Connect
+
Add
diff --git a/ui/src/sources/index.js b/ui/src/sources/index.js index e83c52fac1..4f7c95a887 100644 --- a/ui/src/sources/index.js +++ b/ui/src/sources/index.js @@ -1,3 +1,3 @@ -import SelectSourcePage from './containers/SelectSourcePage'; +import CreateSource from './containers/CreateSource'; import ManageSources from './containers/ManageSources'; -export {SelectSourcePage, ManageSources}; +export {CreateSource, ManageSources}; From 2b8e42c9f7b2b6ba4b5abd206d19d8ba7e3684a8 Mon Sep 17 00:00:00 2001 From: Will Piers Date: Mon, 17 Oct 2016 16:21:22 -0700 Subject: [PATCH 3/3] Add connect link to each source --- ui/src/sources/containers/ManageSources.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/src/sources/containers/ManageSources.js b/ui/src/sources/containers/ManageSources.js index 7880aaf4e2..e79ceac6be 100644 --- a/ui/src/sources/containers/ManageSources.js +++ b/ui/src/sources/containers/ManageSources.js @@ -48,6 +48,7 @@ export const ManageSources = React.createClass({ Host Kapacitor + @@ -58,14 +59,14 @@ export const ManageSources = React.createClass({ {source.name}{source.default ? Default : null} {source.url} {source.links.kapacitors} - Edit + Edit + Connect ); }) } -
Connect
Add