From 8d0b2f38bd8443eaf0dbe5c1bf686337612d14b5 Mon Sep 17 00:00:00 2001 From: Tim Raymond Date: Wed, 28 Sep 2016 11:41:23 -0700 Subject: [PATCH 1/4] Rename Cluster to Sources/add source management link --- ui/src/index.js | 1 + ui/src/side_nav/components/SideNav.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/src/index.js b/ui/src/index.js index 97d1c8b24..751451b46 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -121,6 +121,7 @@ const Root = React.createClass({ + diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index 8bff3b491..b287a79dc 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -22,8 +22,9 @@ const SideNav = React.createClass({ Users - + Overview + Manage Sources Queries Tasks Roles From 26504005cadded1e861bc264907cf4574c5ad5a4 Mon Sep 17 00:00:00 2001 From: Tim Raymond Date: Wed, 28 Sep 2016 11:55:14 -0700 Subject: [PATCH 2/4] Remove the "My Account" link from side nav Issue #123 --- ui/src/account_settings/index.js | 135 -------------------------- ui/src/index.js | 2 - ui/src/side_nav/components/SideNav.js | 5 - 3 files changed, 142 deletions(-) delete mode 100644 ui/src/account_settings/index.js diff --git a/ui/src/account_settings/index.js b/ui/src/account_settings/index.js deleted file mode 100644 index da30804b7..000000000 --- a/ui/src/account_settings/index.js +++ /dev/null @@ -1,135 +0,0 @@ -import React, {PropTypes} from 'react'; -import {meShow, meUpdate} from 'shared/apis'; -import FlashMessages from 'shared/components/FlashMessages'; - -const {func} = PropTypes; -const AccountSettingsPage = React.createClass({ - propTypes: { - addFlashMessage: func.isRequired, - }, - - getInitialState() { - return {}; - }, - - componentDidMount() { - meShow().then(({data: user}) => { - this.setState({user}); - }); - }, - - handleSubmit(e) { - e.preventDefault(); - const email = this.email.value; - const lastName = this.lastName.value; - const firstName = this.firstName.value; - const newUser = Object.assign({}, this.state.user, {lastName, firstName, email}); - meUpdate(newUser).then(() => { - this.props.addFlashMessage({ - text: 'User updated successfully', - type: 'success', - }); - }).catch((err) => { - this.props.addFlashMessage({ - text: err.toString(), - type: 'error', - }); - }); - }, - - handleChangePassword(e) { - e.preventDefault(); - const password = this.newPassword.value; - const confirmation = this.newPasswordConfirmation.value; - const newUser = Object.assign({}, this.state.user, {password, confirmation}); - meUpdate(newUser).then(() => { - this.props.addFlashMessage({ - text: 'Password updated successfully', - type: 'success', - }); - - // reset the form fields - this.newPassword.value = ''; - this.newPasswordConfirmation.value = ''; - }).catch(() => { - this.props.addFlashMessage({ - text: 'Passwords did not match', - type: 'error', - }); - }); - }, - - render() { - const {user} = this.state; - if (!user) { - return null; // or something else, idk - } - - return ( -
-
-
-
-

Account Settings

-
-
-
- -
-
-
-
-
-

Personal Info

-
-
-
- -
- - this.firstName = ref} id="account-first-name" type="text" className="form-control" defaultValue={user.first_name} /> -
-
- - this.lastName = ref} id="account-last-name" type="text" className="form-control" defaultValue={user.last_name} /> -
-
- - this.email = ref} id="account-email" type="text" className="form-control" defaultValue={user.email} placeholder="Enter an email address" name="email" /> -
-
- -
-
-
-
-
-
-

Password

-
-
-
- -
- - this.newPassword = ref} id="account-new-password" type="password" className="form-control" name="password" /> -
-
- - this.newPasswordConfirmation = ref} id="account-confirm-new-password" type="password" className="form-control" name="confirmation" /> -
-
- -
-
-
-
-
-
-
-
- ); - }, -}); - -export default FlashMessages(AccountSettingsPage); diff --git a/ui/src/index.js b/ui/src/index.js index 751451b46..819e73734 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -17,7 +17,6 @@ import SelectSourcePage from 'src/select_source'; import {UsersPage, UserEditPage} from 'src/web_users'; import {ClusterAccountsPage, ClusterAccountPage} from 'src/cluster_accounts'; import {RolesPageContainer, RolePageContainer} from 'src/access_control'; -import AccountSettingsPage from 'src/account_settings'; import NotFound from 'src/shared/components/NotFound'; import NoClusterError from 'src/shared/components/NoClusterError'; import configureStore from 'src/store/configureStore'; @@ -140,7 +139,6 @@ const Root = React.createClass({ -
diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index b287a79dc..a65895473 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -36,11 +36,6 @@ const SideNav = React.createClass({ Data Explorer - - - Settings - Logout - Host List From 5b4c1ca568bb5fef1bf0f5f9542539a3c8a27a9c Mon Sep 17 00:00:00 2001 From: Tim Raymond Date: Wed, 28 Sep 2016 16:12:05 -0700 Subject: [PATCH 3/4] Removed users from SideNav Issue #118 --- ui/src/index.js | 3 - ui/src/side_nav/components/SideNav.js | 4 - ui/src/web_users/components/PageHeader.js | 29 -- .../components/modals/AddClusterLinksModal.js | 75 ------ .../components/modals/DeleteUsers.js | 39 --- .../modals/DissociateUserClusterLink.js | 43 --- .../web_users/components/modals/InviteUser.js | 111 -------- ui/src/web_users/containers/UserEditPage.js | 250 ------------------ ui/src/web_users/containers/UsersPage.js | 186 ------------- ui/src/web_users/index.js | 3 - 10 files changed, 743 deletions(-) delete mode 100644 ui/src/web_users/components/PageHeader.js delete mode 100644 ui/src/web_users/components/modals/AddClusterLinksModal.js delete mode 100644 ui/src/web_users/components/modals/DeleteUsers.js delete mode 100644 ui/src/web_users/components/modals/DissociateUserClusterLink.js delete mode 100644 ui/src/web_users/components/modals/InviteUser.js delete mode 100644 ui/src/web_users/containers/UserEditPage.js delete mode 100644 ui/src/web_users/containers/UsersPage.js delete mode 100644 ui/src/web_users/index.js diff --git a/ui/src/index.js b/ui/src/index.js index 819e73734..3c25526c4 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -14,7 +14,6 @@ import DataExplorer from 'src/chronograf'; import DatabaseManager from 'src/database_manager'; import SignUp from 'src/sign_up'; import SelectSourcePage from 'src/select_source'; -import {UsersPage, UserEditPage} from 'src/web_users'; import {ClusterAccountsPage, ClusterAccountPage} from 'src/cluster_accounts'; import {RolesPageContainer, RolePageContainer} from 'src/access_control'; import NotFound from 'src/shared/components/NotFound'; @@ -136,8 +135,6 @@ const Root = React.createClass({ - - diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index a65895473..d6097389f 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -17,10 +17,6 @@ const SideNav = React.createClass({
- - - Users - Overview diff --git a/ui/src/web_users/components/PageHeader.js b/ui/src/web_users/components/PageHeader.js deleted file mode 100644 index db89b06fc..000000000 --- a/ui/src/web_users/components/PageHeader.js +++ /dev/null @@ -1,29 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {string} = PropTypes; -const Header = React.createClass({ - propTypes: { - activeCluster: string.isRequired, - }, - - render() { - return ( -
-
-
-
-

- Web Users -

-
-
- -
-
-
-
- ); - }, -}); - -export default Header; diff --git a/ui/src/web_users/components/modals/AddClusterLinksModal.js b/ui/src/web_users/components/modals/AddClusterLinksModal.js deleted file mode 100644 index 5a1f0ad49..000000000 --- a/ui/src/web_users/components/modals/AddClusterLinksModal.js +++ /dev/null @@ -1,75 +0,0 @@ -import React, {PropTypes} from 'react'; -import AddClusterAccounts from 'src/shared/components/AddClusterAccounts'; -import {getClusters} from 'shared/apis'; - -const {func, shape, string} = PropTypes; -const AddClusterLinksModal = React.createClass({ - propTypes: { - user: shape({name: string.isRequired}).isRequired, - onAddClusterAccount: func.isRequired, - onCreateClusterLinks: func.isRequired, - }, - - getInitialState() { - return { - clusters: [], - clusterLinks: {}, - }; - }, - - componentDidMount() { - getClusters().then(({data: clusters}) => { - this.setState({clusters}); - }); - }, - - handleSelectClusterAccount({clusterID, accountName}) { - const clusterLinks = Object.assign({}, this.state.clusterLinks, { - [clusterID]: accountName, - }); - this.setState({clusterLinks}); - this.props.onAddClusterAccount(clusterLinks); - }, - - handleSubmit(e) { - e.preventDefault(); - $('#addClusterAccountModal').modal('hide'); // eslint-disable-line no-undef - this.props.onCreateClusterLinks(); - }, - - render() { - return ( - - ); - }, -}); - -export default AddClusterLinksModal; diff --git a/ui/src/web_users/components/modals/DeleteUsers.js b/ui/src/web_users/components/modals/DeleteUsers.js deleted file mode 100644 index 6d273977e..000000000 --- a/ui/src/web_users/components/modals/DeleteUsers.js +++ /dev/null @@ -1,39 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {func, string, number, shape} = PropTypes; -const DeleteUsersModal = React.createClass({ - propTypes: { - handleConfirmDeleteUser: func.isRequired, - userToDelete: shape({ - id: number.isRequired, - name: string.isRequired, - }).isRequired, - }, - - onConfirmDeleteUser() { - this.props.handleConfirmDeleteUser(this.props.userToDelete.id); - }, - - render() { - return ( - - ); - }, -}); - -export default DeleteUsersModal; diff --git a/ui/src/web_users/components/modals/DissociateUserClusterLink.js b/ui/src/web_users/components/modals/DissociateUserClusterLink.js deleted file mode 100644 index 90e8bfbea..000000000 --- a/ui/src/web_users/components/modals/DissociateUserClusterLink.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {func, string, number, shape} = PropTypes; -const DissociateUserClusterLink = React.createClass({ - propTypes: { - handleDissociate: func.isRequired, - clusterLink: shape({ - id: number, - name: string, - cluster_user: string, - }).isRequired, - user: shape({ - name: string, - }).isRequired, - }, - - onConfirmDissociate() { - this.props.handleDissociate(this.props.clusterLink); - }, - - render() { - const {clusterLink, user} = this.props; - return ( - - ); - }, -}); - -export default DissociateUserClusterLink; diff --git a/ui/src/web_users/components/modals/InviteUser.js b/ui/src/web_users/components/modals/InviteUser.js deleted file mode 100644 index 5cb95b844..000000000 --- a/ui/src/web_users/components/modals/InviteUser.js +++ /dev/null @@ -1,111 +0,0 @@ -import React, {PropTypes} from 'react'; -import {getClusters} from 'shared/apis'; -import FlashMessages from 'shared/components/FlashMessages'; -import ClusterAccounts from 'shared/components/AddClusterAccounts'; -import $ from 'jquery'; - -const {string, func} = PropTypes; -const InviteUserModal = React.createClass({ - propTypes: { - clusterID: string.isRequired, - addFlashMessage: func.isRequired, - onCreateWebUser: func.isRequired, - onSelectClusterAccount: func.isRequired, - }, - - getInitialState() { - return { - errors: null, - clusters: [], - clusterLinks: {}, - }; - }, - - componentDidMount() { - getClusters().then(({data}) => { - this.setState({clusters: data}); - }); - }, - - handleSubmit(e) { - e.preventDefault(); - const firstName = this.firstName.value; - const lastName = this.lastName.value; - const email = this.email.value; - const password = this.password.value; - - this.props.onCreateWebUser({clusterID: this.props.clusterID, firstName, lastName, email, password}); - this.cleanup(); - }, - - render() { - return ( - - ); - }, - - cleanup() { - $('.modal').hide(); - $('.modal-backdrop').hide(); - - // reset form values - this.firstName.value = ''; - this.lastName.value = ''; - this.email.value = ''; - this.password.value = ''; - }, -}); - -export default FlashMessages(InviteUserModal); diff --git a/ui/src/web_users/containers/UserEditPage.js b/ui/src/web_users/containers/UserEditPage.js deleted file mode 100644 index 1cad5997a..000000000 --- a/ui/src/web_users/containers/UserEditPage.js +++ /dev/null @@ -1,250 +0,0 @@ -import React, {PropTypes} from 'react'; -import FlashMessages from 'shared/components/FlashMessages'; -import DissociateModal from '../components/modals/DissociateUserClusterLink'; -import AddClusterLinksModal from '../components/modals/AddClusterLinksModal'; -import { - showUser, - updateUser, - deleteUserClusterLink, - batchCreateUserClusterLink, -} from 'shared/apis'; - -const {func, string, shape} = PropTypes; -const WebUserEdit = React.createClass({ - propTypes: { - addFlashMessage: func.isRequired, - params: shape({ - userID: string, - clusterID: string, - }), - }, - - getInitialState() { - return { - linkToDissociate: {}, - }; - }, - - componentDidMount() { - this.getPageData(); - }, - - getPageData() { - const {userID} = this.props.params; - showUser(userID).then(({data}) => { - this.setState({user: data}); - }); - }, - - handleSubmit(e) { - e.preventDefault(); - const email = this.email.value; - const lastName = this.lastName.value; - const firstName = this.firstName.value; - const admin = this.admin.checked; - const password = this.newPassword.value; - const confirmation = this.newPasswordConfirmation.value; - const newUser = Object.assign({}, this.state.user, {lastName, firstName, email, admin, password, confirmation}); - - updateUser(this.props.params.userID, newUser).then(() => { - this.props.addFlashMessage({ - text: 'User updated successfully', - type: 'success', - }); - - this.newPassword.value = ''; - this.newPasswordConfirmation.value = ''; - }).catch((err) => { - this.props.addFlashMessage({ - text: err.toString(), - type: 'error', - }); - }); - }, - - handleAddClusterLinks(clusterLinks) { - this.setState({clusterLinks}); - }, - - handleCreateClusterLinks() { - const {user} = this.state; - const clusterLinks = this.getClusterLinks(); - batchCreateUserClusterLink( - user.id, - clusterLinks, - ).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: `Cluster account added to ${user.name}`, - }); - this.getPageData(); - }).catch((err) => { - this.props.addFlashMessage({ - type: 'error', - text: 'Something went wrong while trying to add cluster account', - }); - console.error(err); // eslint-disable-line no-console - }); - }, - - handleDissociation() { - const {linkToDissociate, user} = this.state; - const {params: {clusterID}} = this.props; - deleteUserClusterLink(clusterID, linkToDissociate.id).then(() => { - this.props.addFlashMessage({ - text: `${user.name} dissociated from ${linkToDissociate.cluster_user}`, - type: 'success', - }); - this.getPageData(); - }).catch(() => { - this.props.addFlashMessage({ - text: `Something went wrong`, - type: 'error', - }); - }); - }, - - handleLinkToDissociate(linkToDissociate) { - this.setState({linkToDissociate}); - }, - - getClusterLinks() { - return Object.keys(this.state.clusterLinks).map((clusterID) => { - return { - cluster_id: clusterID, - cluster_user: this.state.clusterLinks[clusterID], - }; - }); - }, - - render() { - const {user, linkToDissociate} = this.state; - if (!user) { - return null; // or something else, idk - } - - return ( -
-
-
-
-

- {user.name} -  Web User -

-
-
- -
-
-
- -
-
-
-
-
-

Account Details

-
-
-
-
- this.admin = ref} type="checkbox" id="users-header__select-all" defaultChecked={user.admin} /> - -
-
- - this.firstName = ref} id="account-first-name" type="text" className="form-control" defaultValue={user.first_name} /> -
-
- - this.lastName = ref} id="account-last-name" type="text" className="form-control" defaultValue={user.last_name} /> -
-
- - this.email = ref} id="account-email" type="text" className="form-control" defaultValue={user.email} placeholder="Enter an email address" name="email" /> -
-
- - this.newPassword = ref} id="account-new-password" type="password" className="form-control" name="password" /> -
-
- - this.newPasswordConfirmation = ref} id="account-confirm-new-password" type="password" className="form-control" name="confirmation" /> -
-
- -
-
-
-
-
-
-
-
-
-
-

Linked Cluster Accounts

-
-
- {this.renderClusterLinks()} -
-
-
-
-
- - -
- ); - }, - - renderClusterLinks() { - const {user: {cluster_links}} = this.state; - if (!cluster_links.length) { - return ( -
- -

No Cluster Accounts linked to this user

-
- ); - } - - return ( - - - - - - - - - { - cluster_links.map((link) => { - return ( - - - - - - - ); - }) - } - -
AccountCluster
{link.cluster_user}{link.cluster_id} - -
- ); - }, -}); - -export default FlashMessages(WebUserEdit); diff --git a/ui/src/web_users/containers/UsersPage.js b/ui/src/web_users/containers/UsersPage.js deleted file mode 100644 index 3344f796a..000000000 --- a/ui/src/web_users/containers/UsersPage.js +++ /dev/null @@ -1,186 +0,0 @@ -import React, {PropTypes} from 'react'; -import _ from 'lodash'; -import PageHeader from '../components/PageHeader'; -import UsersTable from 'shared/components/UsersTable'; -import InviteUserModal from '../components/modals/InviteUser'; -import FlashMessages from 'shared/components/FlashMessages'; -import DeleteUserModal from '../components/modals/DeleteUsers'; -import { - getWebUsers, - deleteWebUsers, - meShow, - createWebUser, - batchCreateUserClusterLink, -} from 'shared/apis/index'; - -const {string, func} = PropTypes; -const UsersPage = React.createClass({ - propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, - addFlashMessage: PropTypes.func.isRequired, - }, - - getInitialState() { - return { - filterText: '', - users: [], - userToDelete: { - id: 0, - name: '', - }, - me: { - id: 0, - }, - clusterLinks: {}, - }; - }, - - componentDidMount() { - this.refreshUsers(); - meShow().then(({data}) => { - this.setState({me: data}); - }); - }, - - handleCreateWebUser(user) { - const {addFlashMessage} = this.props; - - createWebUser(user).then(({data}) => { - batchCreateUserClusterLink(data.id, this.getClusterLinks()).then(() => { - this.refreshUsers(); - addFlashMessage({ - type: 'success', - text: 'User added successfully', - }); - }).catch((err) => { - this.handleFormError(err, 'Problem adding user'); - }); - }).catch((err) => { - this.handleFormError(err, 'Problem adding cluster account'); - }); - }, - - handleSelectClusterAccount({clusterID, accountName}) { - const clusterLinks = Object.assign({}, this.state.clusterLinks, { - [clusterID]: accountName, - }); - this.setState({clusterLinks}); - }, - - handleUserInput(filterText) { - this.setState({filterText}); - }, - - handleUserToDelete(userToDelete) { - this.setState({userToDelete}); - }, - - handleConfirmDeleteUser(userID) { - deleteWebUsers(userID).then(() => { - this.refreshUsers(); - this.props.addFlashMessage({ - type: 'success', - text: 'User successfully deleted!', - }); - }).catch(() => { - this.props.addFlashMessage({ - type: 'error', - text: 'There was a problem deleting the user...', - }); - }); - }, - - getClusterLinks() { - return Object.keys(this.state.clusterLinks).map((clusterID) => { - return { - cluster_id: clusterID, - cluster_user: this.state.clusterLinks[clusterID], - }; - }); - }, - - refreshUsers() { - getWebUsers(this.props.params.clusterID).then(({data}) => { - this.setState({users: data}); - }); - }, - - handleFormError(err, text) { - const formErrors = _.get(err, 'response.data.errors', null); - const messages = formErrors ? Object.keys(formErrors).map(k => formErrors[k]) : text; - console.error(messages); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: messages, - }); - }, - - render() { - const {users, filterText, me} = this.state; - const {params: {clusterID}} = this.props; - const filteredUsers = users.filter((user) => user.name.toLowerCase().indexOf(filterText.toLowerCase()) > -1); - - return ( -
- - -
-
-
- -
-
-

- -
-
- -
-
-
-
-
- - -
- ); - }, -}); - -const SearchBar = React.createClass({ - propTypes: { - onUserInput: func.isRequired, - filterText: string.isRequired, - }, - - handleChange() { - this.props.onUserInput(this._filterText.value); - }, - - render() { - return ( -
-
- -
- this._filterText = ref} - onChange={this.handleChange} - /> -
- ); - }, -}); - -export default FlashMessages(UsersPage); diff --git a/ui/src/web_users/index.js b/ui/src/web_users/index.js deleted file mode 100644 index 867ce84e3..000000000 --- a/ui/src/web_users/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import UsersPage from './containers/UsersPage'; -import UserEditPage from './containers/UserEditPage'; -export {UsersPage, UserEditPage}; From 4694067cd1ecaa46d2e68b0296635db828be77a6 Mon Sep 17 00:00:00 2001 From: Tim Raymond Date: Wed, 28 Sep 2016 16:21:23 -0700 Subject: [PATCH 4/4] Reorder Side Navigation This order was requested in issue #119. --- ui/src/side_nav/components/SideNav.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index d6097389f..93593871b 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -17,6 +17,14 @@ const SideNav = React.createClass({
+ + + Host List + + + + Data Explorer + Overview @@ -28,14 +36,6 @@ const SideNav = React.createClass({ Database Manager Retention Policies - - - Data Explorer - - - - Host List - ); },