From 1042b585b17467d099a631892fdb6fcd376ddfeb Mon Sep 17 00:00:00 2001 From: Chris Goller Date: Wed, 29 Mar 2017 14:51:17 -0500 Subject: [PATCH] Remove archived enterprise web content --- .../components/RoleClusterAccounts.js | 133 --------- .../access_control/components/RoleHeader.js | 74 ----- archive/access_control/components/RolePage.js | 110 ------- .../access_control/components/RolesPage.js | 55 ---- .../modals/AddClusterAccountModal.js | 110 ------- .../components/modals/CreateRoleModal.js | 51 ---- .../components/modals/DeleteRoleModal.js | 40 --- .../containers/RolePageContainer.js | 192 ------------ .../containers/RolesPageContainer.js | 71 ----- archive/access_control/index.js | 3 - .../components/AddRoleModal.js | 156 ---------- .../components/AttachWebUsersModal.js | 83 ------ .../components/ClusterAccountDetails.js | 93 ------ .../components/ClusterAccountEditPage.js | 238 --------------- .../components/ClusterAccountsPage.js | 48 --- .../components/ClusterAccountsTable.js | 161 ---------- .../components/CreateAccountModal.js | 68 ----- .../components/DeleteClusterAccountModal.js | 51 ---- .../components/DeleteUserModal.js | 37 --- .../cluster_accounts/components/PageHeader.js | 37 --- .../components/RemoveAccountFromRoleModal.js | 38 --- .../components/RemoveUserFromAccountModal.js | 43 --- .../containers/ClusterAccountContainer.js | 278 ------------------ .../ClusterAccountsPageContainer.js | 157 ---------- archive/cluster_accounts/index.js | 4 - .../components/CreateDatabase.js | 97 ------ .../components/DatabaseManager.js | 141 --------- .../containers/DatabaseManagerApp.js | 77 ----- archive/database_manager/index.js | 2 - archive/queries/containers/QueriesPage.js | 187 ------------ archive/queries/index.js | 2 - .../components/CreateRetentionPolicyModal.js | 70 ----- .../components/DropShardModal.js | 74 ----- .../components/RetentionPoliciesHeader.js | 34 --- .../components/RetentionPoliciesList.js | 63 ---- .../components/RetentionPolicyCard.js | 140 --------- .../containers/RetentionPoliciesApp.js | 212 ------------- archive/retention_policies/index.js | 2 - .../sign_up/components/CreateClusterAdmin.js | 79 ----- archive/sign_up/components/CreateWebAdmin.js | 125 -------- archive/sign_up/components/NameCluster.js | 48 --- archive/sign_up/components/NoCluster.js | 33 --- archive/sign_up/index.js | 97 ------ 43 files changed, 3814 deletions(-) delete mode 100644 archive/access_control/components/RoleClusterAccounts.js delete mode 100644 archive/access_control/components/RoleHeader.js delete mode 100644 archive/access_control/components/RolePage.js delete mode 100644 archive/access_control/components/RolesPage.js delete mode 100644 archive/access_control/components/modals/AddClusterAccountModal.js delete mode 100644 archive/access_control/components/modals/CreateRoleModal.js delete mode 100644 archive/access_control/components/modals/DeleteRoleModal.js delete mode 100644 archive/access_control/containers/RolePageContainer.js delete mode 100644 archive/access_control/containers/RolesPageContainer.js delete mode 100644 archive/access_control/index.js delete mode 100644 archive/cluster_accounts/components/AddRoleModal.js delete mode 100644 archive/cluster_accounts/components/AttachWebUsersModal.js delete mode 100644 archive/cluster_accounts/components/ClusterAccountDetails.js delete mode 100644 archive/cluster_accounts/components/ClusterAccountEditPage.js delete mode 100644 archive/cluster_accounts/components/ClusterAccountsPage.js delete mode 100644 archive/cluster_accounts/components/ClusterAccountsTable.js delete mode 100644 archive/cluster_accounts/components/CreateAccountModal.js delete mode 100644 archive/cluster_accounts/components/DeleteClusterAccountModal.js delete mode 100644 archive/cluster_accounts/components/DeleteUserModal.js delete mode 100644 archive/cluster_accounts/components/PageHeader.js delete mode 100644 archive/cluster_accounts/components/RemoveAccountFromRoleModal.js delete mode 100644 archive/cluster_accounts/components/RemoveUserFromAccountModal.js delete mode 100644 archive/cluster_accounts/containers/ClusterAccountContainer.js delete mode 100644 archive/cluster_accounts/containers/ClusterAccountsPageContainer.js delete mode 100644 archive/cluster_accounts/index.js delete mode 100644 archive/database_manager/components/CreateDatabase.js delete mode 100644 archive/database_manager/components/DatabaseManager.js delete mode 100644 archive/database_manager/containers/DatabaseManagerApp.js delete mode 100644 archive/database_manager/index.js delete mode 100644 archive/queries/containers/QueriesPage.js delete mode 100644 archive/queries/index.js delete mode 100644 archive/retention_policies/components/CreateRetentionPolicyModal.js delete mode 100644 archive/retention_policies/components/DropShardModal.js delete mode 100644 archive/retention_policies/components/RetentionPoliciesHeader.js delete mode 100644 archive/retention_policies/components/RetentionPoliciesList.js delete mode 100644 archive/retention_policies/components/RetentionPolicyCard.js delete mode 100644 archive/retention_policies/containers/RetentionPoliciesApp.js delete mode 100644 archive/retention_policies/index.js delete mode 100644 archive/sign_up/components/CreateClusterAdmin.js delete mode 100644 archive/sign_up/components/CreateWebAdmin.js delete mode 100644 archive/sign_up/components/NameCluster.js delete mode 100644 archive/sign_up/components/NoCluster.js delete mode 100644 archive/sign_up/index.js diff --git a/archive/access_control/components/RoleClusterAccounts.js b/archive/access_control/components/RoleClusterAccounts.js deleted file mode 100644 index 910ca77410..0000000000 --- a/archive/access_control/components/RoleClusterAccounts.js +++ /dev/null @@ -1,133 +0,0 @@ -import React, {PropTypes} from 'react'; -import {Link} from 'react-router'; - -const RoleClusterAccounts = React.createClass({ - propTypes: { - clusterID: PropTypes.string.isRequired, - users: PropTypes.arrayOf(PropTypes.string.isRequired), - onRemoveClusterAccount: PropTypes.func.isRequired, - }, - - getDefaultProps() { - return {users: []}; - }, - - getInitialState() { - return { - searchText: '', - }; - }, - - handleSearch(searchText) { - this.setState({searchText}); - }, - - handleRemoveClusterAccount(user) { - this.props.onRemoveClusterAccount(user); - }, - - render() { - const users = this.props.users.filter((user) => { - const name = user.toLowerCase(); - const searchText = this.state.searchText.toLowerCase(); - return name.indexOf(searchText) > -1; - }); - - return ( -
-
- {this.props.users.length ? : null} - {this.props.users.length ? ( - - ) : ( -
- -

No Cluster Accounts found

-
- )} -
-
- ); - }, -}); - -const TableBody = React.createClass({ - propTypes: { - users: PropTypes.arrayOf(PropTypes.string.isRequired), - clusterID: PropTypes.string.isRequired, - onRemoveClusterAccount: PropTypes.func.isRequired, - }, - - render() { - return ( - - - - - - - - {this.props.users.map((user) => { - return ( - - - - - - ); - })} - -
Username
- - {user} - - - -
- ); - }, -}); - -const SearchBar = React.createClass({ - propTypes: { - onSearch: PropTypes.func.isRequired, - searchText: PropTypes.string.isRequired, - }, - - handleChange() { - this.props.onSearch(this._searchText.value); - }, - - render() { - return ( -
-
- -
- this._searchText = ref} - onChange={this.handleChange} - /> -
- ); - }, -}); - -export default RoleClusterAccounts; diff --git a/archive/access_control/components/RoleHeader.js b/archive/access_control/components/RoleHeader.js deleted file mode 100644 index b49b1e05ab..0000000000 --- a/archive/access_control/components/RoleHeader.js +++ /dev/null @@ -1,74 +0,0 @@ -import React, {PropTypes} from 'react'; -import {Link} from 'react-router'; - -const RoleHeader = React.createClass({ - propTypes: { - selectedRole: PropTypes.shape(), - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - })).isRequired, - clusterID: PropTypes.string.isRequired, - activeTab: PropTypes.string, - }, - - getDefaultProps() { - return { - selectedRole: '', - }; - }, - - render() { - return ( -
-
-
-
- -
    - {this.props.roles.map((role) => ( -
  • - - {role.name} - -
  • - ))} -
  • -
  • - - All Roles - -
  • -
-
-
-
- - {this.props.activeTab === 'Permissions' ? ( - - ) : null} - {this.props.activeTab === 'Cluster Accounts' ? ( - - ) : null} -
-
-
- ); - }, -}); - -export default RoleHeader; diff --git a/archive/access_control/components/RolePage.js b/archive/access_control/components/RolePage.js deleted file mode 100644 index 1c0e66c077..0000000000 --- a/archive/access_control/components/RolePage.js +++ /dev/null @@ -1,110 +0,0 @@ -import React, {PropTypes} from 'react'; -import {Tab, Tabs, TabPanel, TabPanels, TabList} from 'src/shared/components/Tabs'; -import RoleHeader from '../components/RoleHeader'; -import RoleClusterAccounts from '../components/RoleClusterAccounts'; -import PermissionsTable from 'src/shared/components/PermissionsTable'; -import AddPermissionModal from 'src/shared/components/AddPermissionModal'; -import AddClusterAccountModal from '../components/modals/AddClusterAccountModal'; -import DeleteRoleModal from '../components/modals/DeleteRoleModal'; - -const {arrayOf, string, shape, func} = PropTypes; -const TABS = ['Permissions', 'Cluster Accounts']; - -const RolePage = React.createClass({ - propTypes: { - // All permissions to populate the "Add permission" modal - allPermissions: arrayOf(shape({ - displayName: string.isRequired, - name: string.isRequired, - description: string.isRequired, - })), - - // All roles to populate the navigation dropdown - roles: arrayOf(shape({})), - role: shape({ - id: string, - name: string.isRequired, - permissions: arrayOf(shape({ - displayName: string.isRequired, - name: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })), - }), - databases: arrayOf(string.isRequired), - clusterID: string.isRequired, - roleSlug: string.isRequired, - onRemoveClusterAccount: func.isRequired, - onDeleteRole: func.isRequired, - onAddPermission: func.isRequired, - onAddClusterAccount: func.isRequired, - onRemovePermission: func.isRequired, - }, - - getInitialState() { - return {activeTab: TABS[0]}; - }, - - handleActivateTab(activeIndex) { - this.setState({activeTab: TABS[activeIndex]}); - }, - - render() { - const {role, roles, allPermissions, databases, clusterID, - onDeleteRole, onRemoveClusterAccount, onAddPermission, onRemovePermission, onAddClusterAccount} = this.props; - - return ( -
- -
-
-
- - - {TABS[0]} - {TABS[1]} - - - - - - - - - - -
-
-
- - - -
- ); - }, -}); - -export default RolePage; diff --git a/archive/access_control/components/RolesPage.js b/archive/access_control/components/RolesPage.js deleted file mode 100644 index 62a7c2710b..0000000000 --- a/archive/access_control/components/RolesPage.js +++ /dev/null @@ -1,55 +0,0 @@ -import React, {PropTypes} from 'react'; -import CreateRoleModal from './modals/CreateRoleModal'; -import RolePanels from 'src/shared/components/RolePanels'; - -const RolesPage = React.createClass({ - propTypes: { - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - users: PropTypes.arrayOf(PropTypes.string), - permissions: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - displayName: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - resources: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired, - })), - })).isRequired, - onCreateRole: PropTypes.func.isRequired, - clusterID: PropTypes.string.isRequired, - }, - - handleCreateRole(roleName) { - this.props.onCreateRole(roleName); - }, - - render() { - return ( -
-
-
-
-

Access Control

-
-
- -
-
-
- -
-
-
-

All Roles

-
- -
-
-
-
- -
- ); - }, -}); - -export default RolesPage; diff --git a/archive/access_control/components/modals/AddClusterAccountModal.js b/archive/access_control/components/modals/AddClusterAccountModal.js deleted file mode 100644 index dd0eac9b26..0000000000 --- a/archive/access_control/components/modals/AddClusterAccountModal.js +++ /dev/null @@ -1,110 +0,0 @@ -import React, {PropTypes} from 'react'; -import AddClusterAccounts from 'src/shared/components/AddClusterAccounts'; -import {getClusterAccounts} from 'src/shared/apis'; - -const {arrayOf, func, string, shape} = PropTypes; - -// Allows a user to add a cluster account to a role. Very similar to other features -// (e.g. adding cluster accounts to a web user), the main difference being that -// we'll only give users the option to select users from the active cluster instead of -// from all clusters. -const AddClusterAccountModal = React.createClass({ - propTypes: { - clusterID: string.isRequired, - onAddClusterAccount: func.isRequired, - // Cluster accounts that already belong to a role so we can filter - // the list of available options. - roleClusterAccounts: arrayOf(string), - role: shape({ - name: PropTypes.string, - }), - }, - - getDefaultProps() { - return {roleClusterAccounts: []}; - }, - - getInitialState() { - return { - selectedAccount: null, - clusterAccounts: [], - error: null, - isFetching: true, - }; - }, - - componentDidMount() { - getClusterAccounts(this.props.clusterID).then((resp) => { - this.setState({clusterAccounts: resp.data.users}); - }).catch(() => { - this.setState({error: 'An error occured.'}); - }).then(() => { - this.setState({isFetching: false}); - }); - }, - - handleSubmit(e) { - e.preventDefault(); - this.props.onAddClusterAccount(this.state.selectedAccount); - $('#addClusterAccountModal').modal('hide'); // eslint-disable-line no-undef - }, - - handleSelectClusterAccount({accountName}) { - this.setState({ - selectedAccount: accountName, - }); - }, - - render() { - if (this.state.isFetching) { - return null; - } - const {role} = this.props; - - // Temporary hack while https://github.com/influxdata/enterprise/issues/948 is resolved. - // We want to use the /api/int/v1/clusters endpoint and just pick the - // Essentially we're taking the raw output from /user and morphing whatthe `AddClusterAccounts` - // modal expects (a cluster with fields defined by the enterprise web database) - const availableClusterAccounts = this.state.clusterAccounts.filter((account) => { - return !this.props.roleClusterAccounts.includes(account.name); - }); - const cluster = { - id: 0, // Only used as a `key` prop - cluster_users: availableClusterAccounts, - cluster_id: this.props.clusterID, - }; - - return ( - - ); - }, -}); - -export default AddClusterAccountModal; diff --git a/archive/access_control/components/modals/CreateRoleModal.js b/archive/access_control/components/modals/CreateRoleModal.js deleted file mode 100644 index 184bfe1fb8..0000000000 --- a/archive/access_control/components/modals/CreateRoleModal.js +++ /dev/null @@ -1,51 +0,0 @@ -import React, {PropTypes} from 'react'; - -const CreateRoleModal = React.createClass({ - propTypes: { - onConfirm: PropTypes.func.isRequired, - }, - - handleSubmit(e) { - e.preventDefault(); - if (this.roleName.value === '') { - return; - } - - this.props.onConfirm(this.roleName.value); - this.roleName.value = ''; - $('#createRoleModal').modal('hide'); // eslint-disable-line no-undef - }, - - render() { - return ( - - ); - }, -}); - -export default CreateRoleModal; diff --git a/archive/access_control/components/modals/DeleteRoleModal.js b/archive/access_control/components/modals/DeleteRoleModal.js deleted file mode 100644 index 16d7d7120b..0000000000 --- a/archive/access_control/components/modals/DeleteRoleModal.js +++ /dev/null @@ -1,40 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {string, func} = PropTypes; - -const DeleteRoleModal = React.createClass({ - propTypes: { - roleName: string.isRequired, - onDeleteRole: func.isRequired, - }, - - handleConfirm() { - $('#deleteRoleModal').modal('hide'); // eslint-disable-line no-undef - this.props.onDeleteRole(); - }, - - render() { - return ( - - ); - }, -}); - -export default DeleteRoleModal; diff --git a/archive/access_control/containers/RolePageContainer.js b/archive/access_control/containers/RolePageContainer.js deleted file mode 100644 index 18a531345e..0000000000 --- a/archive/access_control/containers/RolePageContainer.js +++ /dev/null @@ -1,192 +0,0 @@ -import React, {PropTypes} from 'react'; -import {withRouter} from 'react-router'; -import RolePage from '../components/RolePage'; -import {showDatabases} from 'src/shared/apis/metaQuery'; -import showDatabasesParser from 'shared/parsing/showDatabases'; -import {buildRoles, buildAllPermissions} from 'src/shared/presenters'; -import { - getRoles, - removeAccountsFromRole, - addAccountsToRole, - deleteRole, - addPermissionToRole, - removePermissionFromRole, -} from 'src/shared/apis'; -import _ from 'lodash'; - -export const RolePageContainer = React.createClass({ - propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - roleSlug: PropTypes.string.isRequired, - }).isRequired, - router: React.PropTypes.shape({ - push: React.PropTypes.func.isRequired, - }).isRequired, - addFlashMessage: PropTypes.func, - dataNodes: PropTypes.arrayOf(PropTypes.string.isRequired), - }, - - getInitialState() { - return { - role: {}, - roles: [], - databases: [], - isFetching: true, - }; - }, - - componentDidMount() { - const {clusterID, roleSlug} = this.props.params; - this.getRole(clusterID, roleSlug); - }, - - componentWillReceiveProps(nextProps) { - if (this.props.params.roleSlug !== nextProps.params.roleSlug) { - this.setState(this.getInitialState()); - this.getRole(nextProps.params.clusterID, nextProps.params.roleSlug); - } - }, - - getRole(clusterID, roleName) { - this.setState({isFetching: true}); - Promise.all([ - getRoles(clusterID, roleName), - showDatabases(this.props.dataNodes, this.props.params.clusterID), - ]).then(([rolesResp, dbResp]) => { - // Fetch databases for adding permissions/resources - const {errors, databases} = showDatabasesParser(dbResp.data); - if (errors.length) { - this.props.addFlashMessage({ - type: 'error', - text: `InfluxDB error: ${errors[0]}`, - }); - } - - const roles = buildRoles(rolesResp.data.roles); - const activeRole = roles.find(role => role.name === roleName); - this.setState({ - role: activeRole, - roles, - databases, - isFetching: false, - }); - }).catch(err => { - this.setState({isFetching: false}); - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: `Unable to fetch role! Please try refreshing the page.`, - }); - }); - }, - - handleRemoveClusterAccount(username) { - const {clusterID, roleSlug} = this.props.params; - removeAccountsFromRole(clusterID, roleSlug, [username]).then(() => { - this.setState({ - role: Object.assign({}, this.state.role, { - users: _.reject(this.state.role.users, (user) => user === username), - }), - }); - this.props.addFlashMessage({ - type: 'success', - text: 'Cluster account removed from role!', - }); - }).catch(err => { - this.addErrorNotification(err); - }); - }, - - handleDeleteRole() { - const {clusterID, roleSlug} = this.props.params; - deleteRole(clusterID, roleSlug).then(() => { - // TODO: add success notification when we're implementing them higher in the tree. - // Right now the notification just gets swallowed when we transition to a new route. - this.props.router.push(`/roles`); - }).catch(err => { - console.error(err.toString()); // eslint-disable-line no-console - this.addErrorNotification(err); - }); - }, - - handleAddPermission(permission) { - const {clusterID, roleSlug} = this.props.params; - addPermissionToRole(clusterID, roleSlug, permission).then(() => { - this.getRole(clusterID, roleSlug); - }).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: 'Added permission to role!', - }); - }).catch(err => { - this.addErrorNotification(err); - }); - }, - - handleRemovePermission(permission) { - const {clusterID, roleSlug} = this.props.params; - removePermissionFromRole(clusterID, roleSlug, permission).then(() => { - this.setState({ - role: Object.assign({}, this.state.role, { - permissions: _.reject(this.state.role.permissions, (p) => p.name === permission.name), - }), - }); - this.props.addFlashMessage({ - type: 'success', - text: 'Removed permission from role!', - }); - }).catch(err => { - this.addErrorNotification(err); - }); - }, - - handleAddClusterAccount(clusterAccountName) { - const {clusterID, roleSlug} = this.props.params; - addAccountsToRole(clusterID, roleSlug, [clusterAccountName]).then(() => { - this.getRole(clusterID, roleSlug); - }).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: 'Added cluster account to role!', - }); - }).catch(err => { - this.addErrorNotification(err); - }); - }, - - addErrorNotification(err) { - const text = _.result(err, ['response', 'data', 'error', 'toString'], 'An error occurred.'); - this.props.addFlashMessage({ - type: 'error', - text, - }); - }, - - render() { - if (this.state.isFetching) { - return
; - } - - const {clusterID, roleSlug} = this.props.params; - const {role, roles, databases} = this.state; - - return ( - - ); - }, -}); - -export default withRouter(RolePageContainer); diff --git a/archive/access_control/containers/RolesPageContainer.js b/archive/access_control/containers/RolesPageContainer.js deleted file mode 100644 index f8494fd1c9..0000000000 --- a/archive/access_control/containers/RolesPageContainer.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, {PropTypes} from 'react'; -import {getRoles, createRole} from 'src/shared/apis'; -import {buildRoles} from 'src/shared/presenters'; -import RolesPage from '../components/RolesPage'; -import _ from 'lodash'; - -export const RolesPageContainer = React.createClass({ - propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, - addFlashMessage: PropTypes.func, - }, - - getInitialState() { - return { - roles: [], - }; - }, - - componentDidMount() { - this.fetchRoles(); - }, - - fetchRoles() { - getRoles(this.props.params.clusterID).then((resp) => { - this.setState({ - roles: buildRoles(resp.data.roles), - }); - }).catch((err) => { - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: `Unable to fetch roles! Please try refreshing the page.`, - }); - }); - }, - - handleCreateRole(roleName) { - createRole(this.props.params.clusterID, roleName) - // TODO: this should be an optimistic update, but we can't guarantee that we'll - // get an error when a user tries to make a duplicate role (we don't want to - // display a role twice). See https://github.com/influxdata/plutonium/issues/538 - .then(this.fetchRoles) - .then(() => { - this.props.addFlashMessage({ - type: 'success', - text: 'Role created!', - }); - }) - .catch((err) => { - const text = _.result(err, ['response', 'data', 'error', 'toString'], 'An error occurred.'); - this.props.addFlashMessage({ - type: 'error', - text, - }); - }); - }, - - render() { - return ( - - ); - }, -}); - -export default RolesPageContainer; diff --git a/archive/access_control/index.js b/archive/access_control/index.js deleted file mode 100644 index 6fc1d911f7..0000000000 --- a/archive/access_control/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import RolesPageContainer from './containers/RolesPageContainer'; -import RolePageContainer from './containers/RolePageContainer'; -export {RolesPageContainer, RolePageContainer}; diff --git a/archive/cluster_accounts/components/AddRoleModal.js b/archive/cluster_accounts/components/AddRoleModal.js deleted file mode 100644 index 73367fb802..0000000000 --- a/archive/cluster_accounts/components/AddRoleModal.js +++ /dev/null @@ -1,156 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {shape, string, arrayOf, func} = PropTypes; - -const AddRoleModal = React.createClass({ - propTypes: { - account: shape({ - name: string.isRequired, - hash: string, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - roles: arrayOf(shape({ - name: string.isRequired, - users: arrayOf(string.isRequired).isRequired, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - })).isRequired, - }), - roles: arrayOf(shape({ - name: string.isRequired, - users: arrayOf(string.isRequired).isRequired, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - })), - onAddRoleToAccount: func.isRequired, - }, - - getInitialState() { - return { - selectedRole: this.props.roles[0], - }; - }, - - handleChangeRole(e) { - this.setState({selectedRole: this.props.roles.find((role) => role.name === e.target.value)}); - }, - - handleSubmit(e) { - e.preventDefault(); - $('#addRoleModal').modal('hide'); // eslint-disable-line no-undef - this.props.onAddRoleToAccount(this.state.selectedRole); - }, - - render() { - const {account, roles} = this.props; - const {selectedRole} = this.state; - - if (!roles.length) { - return ( - - ); - } - - return ( - - ); - }, - - renderRoleTable() { - return ( - - - {this.renderPermissions()} - -
- ); - }, - - renderPermissions() { - const role = this.state.selectedRole; - - if (!role.permissions.length) { - return ( - - -
- -

This Role has no Permissions

-
- - - ); - } - - return role.permissions.map((p) => { - return ( - - {p.displayName} - - {p.resources.map((resource, i) => ( -
{resource === '' ? 'All Databases' : resource}
- ))} - - - ); - }); - }, -}); - -export default AddRoleModal; diff --git a/archive/cluster_accounts/components/AttachWebUsersModal.js b/archive/cluster_accounts/components/AttachWebUsersModal.js deleted file mode 100644 index 0e051d7f5b..0000000000 --- a/archive/cluster_accounts/components/AttachWebUsersModal.js +++ /dev/null @@ -1,83 +0,0 @@ -import React, {PropTypes} from 'react'; - -const AttachWebUsers = React.createClass({ - propTypes: { - users: PropTypes.arrayOf(PropTypes.shape()).isRequired, - account: PropTypes.string.isRequired, - onConfirm: PropTypes.func.isRequired, - }, - - getInitialState() { - return { - selectedUsers: [], - }; - }, - - handleConfirm() { - $('#addWebUsers').modal('hide'); // eslint-disable-line no-undef - this.props.onConfirm(this.state.selectedUsers); - // uncheck all the boxes? - }, - - handleSelection(e) { - const checked = e.target.checked; - const id = parseInt(e.target.dataset.id, 10); - const user = this.props.users.find((u) => u.id === id); - const newSelectedUsers = this.state.selectedUsers.slice(0); - - if (checked) { - newSelectedUsers.push(user); - } else { - const userIndex = newSelectedUsers.find(u => u.id === id); - newSelectedUsers.splice(userIndex, 1); - } - - this.setState({selectedUsers: newSelectedUsers}); - }, - - render() { - return ( - - ); - }, -}); - -export default AttachWebUsers; diff --git a/archive/cluster_accounts/components/ClusterAccountDetails.js b/archive/cluster_accounts/components/ClusterAccountDetails.js deleted file mode 100644 index 89bb3e856d..0000000000 --- a/archive/cluster_accounts/components/ClusterAccountDetails.js +++ /dev/null @@ -1,93 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {string, func, bool} = PropTypes; - -const ClusterAccountDetails = React.createClass({ - propTypes: { - name: string.isRequired, - onUpdatePassword: func.isRequired, - showDelete: bool, - }, - - getDefaultProps() { - return { - showDelete: true, - }; - }, - - getInitialState() { - return { - passwordsMatch: true, - }; - }, - - handleSubmit(e) { - e.preventDefault(); - const password = this.password.value; - const confirmation = this.confirmation.value; - const passwordsMatch = password === confirmation; - if (!passwordsMatch) { - return this.setState({passwordsMatch}); - } - - this.props.onUpdatePassword(password); - }, - - render() { - return ( -
-
-
-
- {this.renderPasswordMismatch()} -
- - -
-
- - this.password = password} className="form-control input-lg" type="password" id="password" name="password"/> -
-
- - this.confirmation = confirmation} className="form-control input-lg" type="password" id="password-confirmation" name="confirmation"/> -
-
- -
-
-
-
- {this.props.showDelete ? ( -
-
-
- -
-
-

Delete this cluster account

-

Beware! We won't be able to recover a cluster account once you've deleted it.

-
-
-
- ) : null} -
- ); - }, - - renderPasswordMismatch() { - if (this.state.passwordsMatch) { - return null; - } - - return
Passwords do not match
; - }, -}); - -export default ClusterAccountDetails; diff --git a/archive/cluster_accounts/components/ClusterAccountEditPage.js b/archive/cluster_accounts/components/ClusterAccountEditPage.js deleted file mode 100644 index 660eafbd89..0000000000 --- a/archive/cluster_accounts/components/ClusterAccountEditPage.js +++ /dev/null @@ -1,238 +0,0 @@ -import React, {PropTypes} from 'react'; -import RolePanels from 'src/shared/components/RolePanels'; -import PermissionsTable from 'src/shared/components/PermissionsTable'; -import UsersTable from 'shared/components/UsersTable'; -import ClusterAccountDetails from '../components/ClusterAccountDetails'; -import AddRoleModal from '../components/AddRoleModal'; -import AddPermissionModal from 'shared/components/AddPermissionModal'; -import AttachWebUsers from '../components/AttachWebUsersModal'; -import RemoveAccountFromRoleModal from '../components/RemoveAccountFromRoleModal'; -import RemoveWebUserModal from '../components/RemoveUserFromAccountModal'; -import DeleteClusterAccountModal from '../components/DeleteClusterAccountModal'; -import {Tab, TabList, TabPanels, TabPanel, Tabs} from 'shared/components/Tabs'; - -const {shape, string, func, arrayOf, number, bool} = PropTypes; -const TABS = ['Roles', 'Permissions', 'Account Details', 'Web Users']; - -export const ClusterAccountEditPage = React.createClass({ - propTypes: { - // All permissions to populate the "Add permission" modal - allPermissions: arrayOf(shape({ - displayName: string.isRequired, - name: string.isRequired, - description: string.isRequired, - })), - clusterID: string.isRequired, - accountID: string.isRequired, - account: shape({ - name: string.isRequired, - hash: string, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - roles: arrayOf(shape({ - name: string.isRequired, - users: arrayOf(string.isRequired).isRequired, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - })).isRequired, - }), - roles: arrayOf(shape({ - name: string.isRequired, - users: arrayOf(string.isRequired).isRequired, - permissions: arrayOf(shape({ - name: string.isRequired, - displayName: string.isRequired, - description: string.isRequired, - resources: arrayOf(string.isRequired).isRequired, - })).isRequired, - })), - databases: arrayOf(string.isRequired), - assignedWebUsers: arrayOf(shape({ - id: number.isRequired, - name: string.isRequired, - email: string.isRequired, - admin: bool.isRequired, - })), - unassignedWebUsers: arrayOf(shape({ - id: number.isRequired, - name: string.isRequired, - email: string.isRequired, - admin: bool.isRequired, - })), - me: shape(), - onUpdatePassword: func.isRequired, - onRemoveAccountFromRole: func.isRequired, - onRemoveWebUserFromAccount: func.isRequired, - onAddRoleToAccount: func.isRequired, - onAddPermission: func.isRequired, - onRemovePermission: func.isRequired, - onAddWebUsersToAccount: func.isRequired, - onDeleteAccount: func.isRequired, - }, - - getInitialState() { - return { - roleToRemove: {}, - userToRemove: {}, - activeTab: TABS[0], - }; - }, - - handleActivateTab(activeIndex) { - this.setState({activeTab: TABS[activeIndex]}); - }, - - handleRemoveAccountFromRole(role) { - this.setState({roleToRemove: role}); - }, - - handleUserToRemove(userToRemove) { - this.setState({userToRemove}); - }, - - getUnassignedRoles() { - return this.props.roles.filter(role => { - return !this.props.account.roles.map(r => r.name).includes(role.name); - }); - }, - - render() { - const {clusterID, accountID, account, databases, onAddPermission, me, - assignedWebUsers, unassignedWebUsers, onAddWebUsersToAccount, onRemovePermission, onDeleteAccount} = this.props; - - if (!account || !Object.keys(me).length) { - return null; // TODO: 404? - } - - return ( -
-
-
-
-

- {accountID} Cluster Account -

-
- {this.renderActions()} -
-
- -
-
-
- - - {TABS.map(tab => {tab})} - - - - - - - - - - - cl.cluster_user !== account.name)} - name={account.name} - onUpdatePassword={this.props.onUpdatePassword} - /> - - -
-
- -
-
-
-
-
-
-
-
- - this.props.onRemoveAccountFromRole(this.state.roleToRemove)} - /> - - this.props.onRemoveWebUserFromAccount(this.state.userToRemove)} - user={this.state.userToRemove.name} - /> - - -
- ); - }, - - renderActions() { - const {activeTab} = this.state; - return ( -
- {activeTab === 'Roles' ? ( - - ) : null} - {activeTab === 'Permissions' ? ( - - ) : null} - {activeTab === 'Web Users' ? ( - - ) : null} -
- ); - }, -}); - -export default ClusterAccountEditPage; diff --git a/archive/cluster_accounts/components/ClusterAccountsPage.js b/archive/cluster_accounts/components/ClusterAccountsPage.js deleted file mode 100644 index 88abbbe2af..0000000000 --- a/archive/cluster_accounts/components/ClusterAccountsPage.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, {PropTypes} from 'react'; -import PageHeader from '../components/PageHeader'; -import ClusterAccountsTable from '../components/ClusterAccountsTable'; - -const ClusterAccountsPage = React.createClass({ - propTypes: { - clusterID: PropTypes.string.isRequired, - users: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - })), - })), - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.shape, - })), - onDeleteAccount: PropTypes.func.isRequired, - onCreateAccount: PropTypes.func.isRequired, - me: PropTypes.shape(), - }, - - render() { - const {clusterID, users, roles, onCreateAccount, me} = this.props; - - return ( -
- -
-
-
- -
-
-
-
- ); - }, -}); - -export default ClusterAccountsPage; diff --git a/archive/cluster_accounts/components/ClusterAccountsTable.js b/archive/cluster_accounts/components/ClusterAccountsTable.js deleted file mode 100644 index 8b10e5e9e0..0000000000 --- a/archive/cluster_accounts/components/ClusterAccountsTable.js +++ /dev/null @@ -1,161 +0,0 @@ -import React, {PropTypes} from 'react'; -import {Link} from 'react-router'; - -const ClusterAccountsTable = React.createClass({ - propTypes: { - clusterID: PropTypes.string.isRequired, - users: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - })).isRequired, - })), - onDeleteAccount: PropTypes.func.isRequired, - me: PropTypes.shape(), - }, - - getInitialState() { - return { - searchText: '', - }; - }, - - handleSearch(searchText) { - this.setState({searchText}); - }, - - handleDeleteAccount(user) { - this.props.onDeleteAccount(user); - }, - - render() { - const users = this.props.users.filter((user) => { - const name = user.name.toLowerCase(); - const searchText = this.state.searchText.toLowerCase(); - return name.indexOf(searchText) > -1; - }); - - return ( -
-
-

Cluster Accounts

- -
- -
- -
-
- ); - }, -}); - -const TableBody = React.createClass({ - propTypes: { - users: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.isRequired, - })).isRequired, - })), - clusterID: PropTypes.string.isRequired, - onDeleteAccount: PropTypes.func.isRequired, - me: PropTypes.shape(), - }, - - render() { - if (!this.props.users.length) { - return ( -
- -

No Cluster Accounts

-
- ); - } - - return ( - - - - - - - - {this.props.users.map((user) => { - return ( - - - - - - ); - })} - -
UsernameRoles
- - {user.name} - - {user.roles.map((r) => r.name).join(', ')} - {this.renderDeleteAccount(user)} -
- ); - }, - - renderDeleteAccount(clusterAccount) { - const currentUserIsAssociatedWithAccount = this.props.me.cluster_links.some(cl => ( - cl.cluster_user === clusterAccount.name - )); - const title = currentUserIsAssociatedWithAccount ? - 'You can\'t remove a cluster account that you are associated with.' - : 'Delete cluster account'; - - return ( - - ); - }, -}); - -const SearchBar = React.createClass({ - propTypes: { - onSearch: PropTypes.func.isRequired, - searchText: PropTypes.string.isRequired, - }, - - handleChange() { - this.props.onSearch(this._searchText.value); - }, - - render() { - return ( -
-
- -
- this._searchText = ref} - onChange={this.handleChange} - /> -
- ); - }, -}); - -export default ClusterAccountsTable; diff --git a/archive/cluster_accounts/components/CreateAccountModal.js b/archive/cluster_accounts/components/CreateAccountModal.js deleted file mode 100644 index 9de0661fd5..0000000000 --- a/archive/cluster_accounts/components/CreateAccountModal.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, {PropTypes} from 'react'; - -const CreateAccountModal = React.createClass({ - propTypes: { - onCreateAccount: PropTypes.func.isRequired, - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.shape, - })), - }, - - handleConfirm(e) { - e.preventDefault(); - - const name = this.name.value; - const password = this.password.value; - const role = this.accountRole.value; - - $('#createAccountModal').modal('hide'); // eslint-disable-line no-undef - this.props.onCreateAccount(name, password, role); - }, - - render() { - return ( - - ); - }, -}); - -export default CreateAccountModal; diff --git a/archive/cluster_accounts/components/DeleteClusterAccountModal.js b/archive/cluster_accounts/components/DeleteClusterAccountModal.js deleted file mode 100644 index c758505be2..0000000000 --- a/archive/cluster_accounts/components/DeleteClusterAccountModal.js +++ /dev/null @@ -1,51 +0,0 @@ -import React, {PropTypes} from 'react'; - -const DeleteClusterAccountModal = React.createClass({ - propTypes: { - onConfirm: PropTypes.func.isRequired, - account: PropTypes.shape({ - name: PropTypes.string, - }), - webUsers: PropTypes.arrayOf(PropTypes.shape()), // TODO - }, - - handleConfirm() { - this.props.onConfirm(); - }, - - render() { - return ( - - ); - }, -}); - -export default DeleteClusterAccountModal; diff --git a/archive/cluster_accounts/components/DeleteUserModal.js b/archive/cluster_accounts/components/DeleteUserModal.js deleted file mode 100644 index 1f9ca62b7c..0000000000 --- a/archive/cluster_accounts/components/DeleteUserModal.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, {PropTypes} from 'react'; - -const DeleteUserModal = React.createClass({ - propTypes: { - onConfirm: PropTypes.func.isRequired, - user: PropTypes.shape({ - name: PropTypes.string, - }), - }, - - handleConfirm() { - this.props.onConfirm(this.props.user); - }, - - render() { - return ( - - ); - }, -}); - -export default DeleteUserModal; diff --git a/archive/cluster_accounts/components/PageHeader.js b/archive/cluster_accounts/components/PageHeader.js deleted file mode 100644 index b8f5e19a23..0000000000 --- a/archive/cluster_accounts/components/PageHeader.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, {PropTypes} from 'react'; -import CreateAccountModal from './CreateAccountModal'; - -const Header = React.createClass({ - propTypes: { - onCreateAccount: PropTypes.func, - roles: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.shape, - })), - }, - - render() { - const {roles, onCreateAccount} = this.props; - - return ( -
-
-
-
-

- Access Control -

-
-
- -
-
-
- -
- ); - }, -}); - -export default Header; diff --git a/archive/cluster_accounts/components/RemoveAccountFromRoleModal.js b/archive/cluster_accounts/components/RemoveAccountFromRoleModal.js deleted file mode 100644 index 5b293bc485..0000000000 --- a/archive/cluster_accounts/components/RemoveAccountFromRoleModal.js +++ /dev/null @@ -1,38 +0,0 @@ -import React, {PropTypes} from 'react'; - -const RemoveAccountFromRoleModal = React.createClass({ - propTypes: { - roleName: PropTypes.string, - onConfirm: PropTypes.func.isRequired, - }, - - handleConfirm() { - $('#removeAccountFromRoleModal').modal('hide'); // eslint-disable-line no-undef - this.props.onConfirm(); - }, - - render() { - return ( - - ); - }, -}); - -export default RemoveAccountFromRoleModal; diff --git a/archive/cluster_accounts/components/RemoveUserFromAccountModal.js b/archive/cluster_accounts/components/RemoveUserFromAccountModal.js deleted file mode 100644 index fc17f8d721..0000000000 --- a/archive/cluster_accounts/components/RemoveUserFromAccountModal.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {string, func} = PropTypes; - -const RemoveWebUserModal = React.createClass({ - propTypes: { - user: string, - onRemoveWebUser: func.isRequired, - account: string.isRequired, - }, - - handleConfirm() { - $('#deleteUsersModal').modal('hide'); // eslint-disable-line no-undef - this.props.onRemoveWebUser(); - }, - - render() { - return ( - - ); - }, -}); - -export default RemoveWebUserModal; diff --git a/archive/cluster_accounts/containers/ClusterAccountContainer.js b/archive/cluster_accounts/containers/ClusterAccountContainer.js deleted file mode 100644 index 96fab4ddee..0000000000 --- a/archive/cluster_accounts/containers/ClusterAccountContainer.js +++ /dev/null @@ -1,278 +0,0 @@ -import React, {PropTypes} from 'react'; -import _ from 'lodash'; -import {withRouter} from 'react-router'; -import ClusterAccountEditPage from '../components/ClusterAccountEditPage'; -import {buildClusterAccounts, buildRoles, buildAllPermissions, buildPermission} from 'src/shared/presenters'; -import {showDatabases} from 'src/shared/apis/metaQuery'; -import showDatabasesParser from 'shared/parsing/showDatabases'; -import { - addPermissionToAccount, - removePermissionFromAccount, - deleteUserClusterLink, - getUserClusterLinks, - getClusterAccount, - getWebUsers, - getRoles, - addWebUsersToClusterAccount, - updateClusterAccountPassword, - removeAccountsFromRole, - addAccountsToRole, - meShow, - deleteClusterAccount, - getWebUsersByClusterAccount, -} from 'shared/apis'; - -const {shape, string, func, arrayOf} = PropTypes; - -export const ClusterAccountContainer = React.createClass({ - propTypes: { - dataNodes: arrayOf(string.isRequired), - params: shape({ - clusterID: string.isRequired, - accountID: string.isRequired, - }).isRequired, - router: shape({ - push: func.isRequired, - }).isRequired, - addFlashMessage: func, - }, - - getInitialState() { - return { - account: null, - roles: [], - databases: [], - assignedWebUsers: [], - unassignedWebUsers: [], - me: {}, - }; - }, - - componentDidMount() { - const {accountID, clusterID} = this.props.params; - const {dataNodes} = this.props; - - Promise.all([ - getClusterAccount(clusterID, accountID), - getRoles(clusterID), - showDatabases(dataNodes, clusterID), - getWebUsersByClusterAccount(clusterID, accountID), - getWebUsers(clusterID), - meShow(), - ]).then(([ - {data: {users}}, - {data: {roles}}, - {data: dbs}, - {data: assignedWebUsers}, - {data: allUsers}, - {data: me}, - ]) => { - const account = buildClusterAccounts(users, roles)[0]; - const presentedRoles = buildRoles(roles); - this.setState({ - account, - assignedWebUsers, - roles: presentedRoles, - databases: showDatabasesParser(dbs).databases, - unassignedWebUsers: _.differenceBy(allUsers, assignedWebUsers, (u) => u.id), - me, - }); - }).catch(err => { - this.props.addFlashMessage({ - type: 'error', - text: `An error occured. Please try refreshing the page. ${err.message}`, - }); - }); - }, - - handleUpdatePassword(password) { - updateClusterAccountPassword(this.props.params.clusterID, this.state.account.name, password).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: 'Password successfully updated :)', - }); - }).catch(() => { - this.props.addFlashMessage({ - type: 'error', - text: 'There was a problem updating password :(', - }); - }); - }, - - handleAddPermission({name, resources}) { - const {clusterID} = this.props.params; - const {account} = this.state; - addPermissionToAccount(clusterID, account.name, name, resources).then(() => { - const newPermissions = account.permissions.map(p => p.name).includes(name) ? - account.permissions - : account.permissions.concat(buildPermission(name, resources)); - - this.setState({ - account: Object.assign({}, account, {permissions: newPermissions}), - }, () => { - this.props.addFlashMessage({ - type: 'success', - text: 'Permission successfully added :)', - }); - }); - }).catch(() => { - this.props.addFlashMessage({ - type: 'error', - text: 'There was a problem adding the permission :(', - }); - }); - }, - - handleRemovePermission(permission) { - const {clusterID} = this.props.params; - const {account} = this.state; - removePermissionFromAccount(clusterID, account.name, permission).then(() => { - this.setState({ - account: Object.assign({}, this.state.account, { - permissions: _.reject(this.state.account.permissions, (p) => p.name === permission.name), - }), - }); - this.props.addFlashMessage({ - type: 'success', - text: 'Removed permission from cluster account!', - }); - }).catch(err => { - const text = _.result(err, ['response', 'data', 'error'], 'An error occurred.'); - this.props.addFlashMessage({ - type: 'error', - text, - }); - }); - }, - - handleRemoveAccountFromRole(role) { - const {clusterID, accountID} = this.props.params; - removeAccountsFromRole(clusterID, role.name, [accountID]).then(() => { - this.setState({ - account: Object.assign({}, this.state.account, { - roles: this.state.account.roles.filter(r => r.name !== role.name), - }), - }); - this.props.addFlashMessage({ - type: 'success', - text: 'Cluster account removed from role!', - }); - }).catch(err => { - this.props.addFlashMessage({ - type: 'error', - text: `An error occured. ${err.message}.`, - }); - }); - }, - - handleRemoveWebUserFromAccount(user) { - const {clusterID} = this.props.params; - // TODO: update this process to just include a call to - // deleteUserClusterLinkByUserID which is currently in development - getUserClusterLinks(clusterID).then(({data}) => { - const clusterLinkToDelete = data.find((cl) => cl.cluster_id === clusterID && cl.user_id === user.id); - deleteUserClusterLink(clusterID, clusterLinkToDelete.id).then(() => { - this.setState({assignedWebUsers: this.state.assignedWebUsers.filter(u => u.id !== user.id)}); - - this.props.addFlashMessage({ - type: 'success', - text: `${user.name} removed from this cluster account`, - }); - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: 'Something went wrong while removing this user', - }); - }); - }); - }, - - handleAddRoleToAccount(role) { - const {clusterID, accountID} = this.props.params; - addAccountsToRole(clusterID, role.name, [accountID]).then(() => { - this.setState({ - account: Object.assign({}, this.state.account, { - roles: this.state.account.roles.concat(role), - }), - }); - this.props.addFlashMessage({ - type: 'success', - text: 'Cluster account added to role!', - }); - }).catch(err => { - this.props.addFlashMessage({ - type: 'error', - text: `An error occured. ${err.message}.`, - }); - }); - }, - - handleAddWebUsersToAccount(users) { - const {clusterID, accountID} = this.props.params; - const userIDs = users.map((u) => { - return { - user_id: u.id, - }; - }); - - addWebUsersToClusterAccount(clusterID, accountID, userIDs).then(() => { - this.setState({assignedWebUsers: this.state.assignedWebUsers.concat(users)}); - this.props.addFlashMessage({ - type: 'success', - text: `Web users added to ${accountID}`, - }); - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: `Something went wrong`, - }); - }); - }, - - handleDeleteAccount() { - const {clusterID, accountID} = this.props.params; - deleteClusterAccount(clusterID, accountID).then(() => { - this.props.router.push(`/accounts`); - this.props.addFlashMessage({ - type: 'success', - text: 'Cluster account deleted!', - }); - }).catch(err => { - this.props.addFlashMessage({ - type: 'error', - text: `An error occured. ${err.message}.`, - }); - }); - }, - - render() { - const {clusterID, accountID} = this.props.params; - const {account, databases, roles, me} = this.state; - - return ( - - ); - }, -}); - -export default withRouter(ClusterAccountContainer); diff --git a/archive/cluster_accounts/containers/ClusterAccountsPageContainer.js b/archive/cluster_accounts/containers/ClusterAccountsPageContainer.js deleted file mode 100644 index 12cb4fe352..0000000000 --- a/archive/cluster_accounts/containers/ClusterAccountsPageContainer.js +++ /dev/null @@ -1,157 +0,0 @@ -import React, {PropTypes} from 'react'; -import ClusterAccountsPage from '../components/ClusterAccountsPage'; -import DeleteClusterAccountModal from '../components/DeleteClusterAccountModal'; -import {buildClusterAccounts} from 'src/shared/presenters'; -import { - getClusterAccounts, - getRoles, - deleteClusterAccount, - getWebUsersByClusterAccount, - meShow, - addUsersToRole, - createClusterAccount, -} from 'src/shared/apis'; -import _ from 'lodash'; - -export const ClusterAccountsPageContainer = React.createClass({ - propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, - addFlashMessage: PropTypes.func.isRequired, - }, - - getInitialState() { - return { - users: [], - roles: [], - - // List of associated web users to display when deleting a cluster account. - webUsers: [], - - // This is an unfortunate solution to using bootstrap to open modals. - // The modal will have already been rendered in this component by the - // time a user chooses "Remove" from one of the rows in the users table. - userToDelete: null, - }; - }, - - componentDidMount() { - const {clusterID} = this.props.params; - Promise.all([ - getClusterAccounts(clusterID), - getRoles(clusterID), - meShow(), - ]).then(([accountsResp, rolesResp, me]) => { - this.setState({ - users: buildClusterAccounts(accountsResp.data.users, rolesResp.data.roles), - roles: rolesResp.data.roles, - me: me.data, - }); - }); - }, - - // Ensures the modal will remove the correct user. TODO: our own modals - handleDeleteAccount(account) { - getWebUsersByClusterAccount(this.props.params.clusterID, account.name).then(resp => { - this.setState({ - webUsers: resp.data, - userToDelete: account, - }); - }).catch(err => { - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: 'An error occured while trying to remove a cluster account.', - }); - }); - }, - - handleDeleteConfirm() { - const {name} = this.state.userToDelete; - deleteClusterAccount(this.props.params.clusterID, name).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: 'Cluster account deleted!', - }); - - this.setState({ - users: _.reject(this.state.users, (user) => user.name === name), - }); - }).catch((err) => { - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: 'An error occured while trying to remove a cluster account.', - }); - }); - }, - - handleCreateAccount(name, password, roleName) { - const {clusterID} = this.props.params; - const {users, roles} = this.state; - createClusterAccount(clusterID, name, password).then(() => { - addUsersToRole(clusterID, roleName, [name]).then(() => { - this.props.addFlashMessage({ - type: 'success', - text: `User ${name} added with the ${roleName} role`, - }); - - // add user to role - const newRoles = roles.map((role) => { - if (role.name !== roleName) { - return role; - } - - return Object.assign({}, role, { - users: role.users ? role.users.concat(name) : [name], - }); - }); - - const newUser = buildClusterAccounts([{name}], newRoles); - this.setState({ - roles: newRoles, - users: users.concat(newUser), - }); - }).catch((err) => { - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: `An error occured while assigning ${name} to the ${roleName} role`, - }); - }); - }).catch((err) => { - const msg = _.get(err, 'response.data.error', ''); - console.error(err.toString()); // eslint-disable-line no-console - this.props.addFlashMessage({ - type: 'error', - text: `An error occured creating user ${name}. ${msg}`, - }); - }); - }, - - render() { - const {clusterID} = this.props.params; - const {users, me, roles} = this.state; - - return ( -
- - -
- ); - }, -}); - -export default ClusterAccountsPageContainer; diff --git a/archive/cluster_accounts/index.js b/archive/cluster_accounts/index.js deleted file mode 100644 index ae89e0f5c2..0000000000 --- a/archive/cluster_accounts/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import ClusterAccountsPage from './containers/ClusterAccountsPageContainer'; -import ClusterAccountPage from './containers/ClusterAccountContainer'; -export {ClusterAccountsPage, ClusterAccountPage}; - diff --git a/archive/database_manager/components/CreateDatabase.js b/archive/database_manager/components/CreateDatabase.js deleted file mode 100644 index 0223bb6547..0000000000 --- a/archive/database_manager/components/CreateDatabase.js +++ /dev/null @@ -1,97 +0,0 @@ -import React, {PropTypes} from 'react'; - -const {arrayOf, number, func} = PropTypes; -const CreateDatabase = React.createClass({ - propTypes: { - replicationFactors: arrayOf(number.isRequired).isRequired, - onCreateDatabase: func.isRequired, - }, - - getInitialState() { - return { - rpName: '', - database: '', - duration: '24h', - replicaN: '1', - }; - }, - - handleRpNameChange(e) { - this.setState({rpName: e.target.value}); - }, - - handleDatabaseNameChange(e) { - this.setState({database: e.target.value}); - }, - - handleSelectDuration(e) { - this.setState({duration: e.target.value}); - }, - - handleSelectReplicaN(e) { - this.setState({replicaN: e.target.value}); - }, - - handleSubmit() { - const {rpName, database, duration, replicaN} = this.state; - this.props.onCreateDatabase({rpName, database, duration, replicaN}); - }, - - - render() { - const {database, rpName, duration, replicaN} = this.state; - - return ( - - ); - }, -}); - -export default CreateDatabase; diff --git a/archive/database_manager/components/DatabaseManager.js b/archive/database_manager/components/DatabaseManager.js deleted file mode 100644 index 52a4b89479..0000000000 --- a/archive/database_manager/components/DatabaseManager.js +++ /dev/null @@ -1,141 +0,0 @@ -import React, {PropTypes} from 'react'; -import {Link} from 'react-router'; - -import CreateDatabase from './CreateDatabase'; - -const {number, string, shape, arrayOf, func} = PropTypes; - -const DatabaseManager = React.createClass({ - propTypes: { - database: string.isRequired, - databases: arrayOf(shape({})).isRequired, - dbStats: shape({ - diskBytes: string.isRequired, - numMeasurements: number.isRequired, - numSeries: number.isRequired, - }), - users: arrayOf(shape({ - id: number, - name: string.isRequired, - roles: string.isRequired, - })).isRequired, - queries: arrayOf(string).isRequired, - replicationFactors: arrayOf(number).isRequired, - onClickDatabase: func.isRequired, - onCreateDatabase: func.isRequired, - }, - - render() { - const {database, databases, dbStats, queries, users, - replicationFactors, onClickDatabase, onCreateDatabase} = this.props; - - return ( -
-
-
-
-
- -
    - { - databases.map((db) => { - return
  • onClickDatabase(db.Name)} key={db.Name}>{db.Name}
  • ; - }) - } -
-
-
-
- -
-
-
- -
-
-
-
-
-

Database Stats

-
-
-
-
-

{dbStats.diskBytes}

-

On Disk

-
-
-

{dbStats.numMeasurements}

-

Measurements

-
-
-

{dbStats.numSeries}

-

Series

-
-
-
-
-
- -
-
-
-

Users

-
-
- - - - - - - - - { - users.map((user) => { - return ( - - - - - ); - }) - } - -
NameRole
{user.name}{user.roles}
-
-
-
- -
-
-
-
-
-

Continuous Queries Associated

-
-
- { - queries.length ? queries.map((query, i) =>
{query}
) : - ( -
- -

No queries to display

-
- ) - } -
-
-
-
-
- -
- ); - }, -}); - -export default DatabaseManager; diff --git a/archive/database_manager/containers/DatabaseManagerApp.js b/archive/database_manager/containers/DatabaseManagerApp.js deleted file mode 100644 index 60cafd2b7f..0000000000 --- a/archive/database_manager/containers/DatabaseManagerApp.js +++ /dev/null @@ -1,77 +0,0 @@ -import React, {PropTypes} from 'react'; -import {getDatabaseManager, createDatabase} from 'shared/apis/index'; -import DatabaseManager from '../components/DatabaseManager'; - -const {shape, string} = PropTypes; - -const DatabaseManagerApp = React.createClass({ - propTypes: { - params: shape({ - clusterID: string.isRequired, - database: string.isRequired, - }).isRequired, - }, - - componentDidMount() { - this.getData(); - }, - - getInitialState() { - return { - databases: [], - dbStats: { - diskBytes: '', - numMeasurements: 0, - numSeries: 0, - }, - users: [], - queries: [], - replicationFactors: [], - selectedDatabase: null, - }; - }, - - getData(selectedDatabase) { - const {clusterID, database} = this.props.params; - getDatabaseManager(clusterID, selectedDatabase || database) - .then(({data}) => { - this.setState({ - databases: data.databases, - dbStats: data.databaseStats, - users: data.users, - queries: data.queries || [], - replicationFactors: data.replicationFactors, - }); - }); - }, - - handleClickDatabase(selectedDatabase) { - this.getData(selectedDatabase); - this.setState({selectedDatabase}); - }, - - handleCreateDatabase(db) { - createDatabase(db); - }, - - render() { - const {databases, dbStats, queries, users, replicationFactors} = this.state; - const {clusterID, database} = this.props.params; - - return ( - - ); - }, -}); - -export default DatabaseManagerApp; diff --git a/archive/database_manager/index.js b/archive/database_manager/index.js deleted file mode 100644 index 625c7eb7f5..0000000000 --- a/archive/database_manager/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import DatabaseManagerApp from './containers/DatabaseManagerApp'; -export default DatabaseManagerApp; diff --git a/archive/queries/containers/QueriesPage.js b/archive/queries/containers/QueriesPage.js deleted file mode 100644 index 533f7b684e..0000000000 --- a/archive/queries/containers/QueriesPage.js +++ /dev/null @@ -1,187 +0,0 @@ -import React, {PropTypes} from 'react'; -import flatten from 'lodash/flatten'; -import reject from 'lodash/reject'; -import uniqBy from 'lodash/uniqBy'; -import { - showDatabases, - showQueries, - killQuery, -} from 'shared/apis/metaQuery'; - -import showDatabasesParser from 'shared/parsing/showDatabases'; -import showQueriesParser from 'shared/parsing/showQueries'; - -const times = [ - {test: /ns/, magnitude: 0}, - {test: /^\d*u/, magnitude: 1}, - {test: /^\d*ms/, magnitude: 2}, - {test: /^\d*s/, magnitude: 3}, - {test: /^\d*m\d*s/, magnitude: 4}, - {test: /^\d*h\d*m\d*s/, magnitude: 5}, -]; - -export const QueriesPage = React.createClass({ - propTypes: { - dataNodes: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired, - addFlashMessage: PropTypes.func, - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }), - }, - - getInitialState() { - return { - queries: [], - queryIDToKill: null, - }; - }, - - componentDidMount() { - this.updateQueries(); - const updateInterval = 5000; - this.intervalID = setInterval(this.updateQueries, updateInterval); - }, - - componentWillUnmount() { - clearInterval(this.intervalID); - }, - - updateQueries() { - const {dataNodes, addFlashMessage, params} = this.props; - showDatabases(dataNodes, params.clusterID).then((resp) => { - const {databases, errors} = showDatabasesParser(resp.data); - if (errors.length) { - errors.forEach((message) => addFlashMessage({type: 'error', text: message})); - return; - } - - const fetches = databases.map((db) => showQueries(dataNodes, db, params.clusterID)); - - Promise.all(fetches).then((queryResponses) => { - const allQueries = []; - queryResponses.forEach((queryResponse) => { - const result = showQueriesParser(queryResponse.data); - if (result.errors.length) { - result.erorrs.forEach((message) => this.props.addFlashMessage({type: 'error', text: message})); - } - - allQueries.push(...result.queries); - }); - - const queries = uniqBy(flatten(allQueries), (q) => q.id); - - // sorting queries by magnitude, so generally longer queries will appear atop the list - const sortedQueries = queries.sort((a, b) => { - const aTime = times.find((t) => a.duration.match(t.test)); - const bTime = times.find((t) => b.duration.match(t.test)); - return +aTime.magnitude <= +bTime.magnitude; - }); - this.setState({ - queries: sortedQueries, - }); - }); - }); - }, - - render() { - const {queries} = this.state; - return ( -
-
-
-
-

- Queries -

-
-
-
- -
-
-
-
-
- - - - - - - - - - - {queries.map((q) => { - return ( - - - - - - - ); - })} - -
DatabaseQueryRunning
{q.database}{q.query}{q.duration} - -
-
-
-
-
-
- - -
- ); - }, - - handleKillQuery(e) { - e.stopPropagation(); - const id = e.target.dataset.queryId; - this.setState({ - queryIDToKill: id, - }); - }, - - handleConfirmKillQuery() { - const {queryIDToKill} = this.state; - if (queryIDToKill === null) { - return; - } - - // optimitstic update - const {queries} = this.state; - this.setState({ - queries: reject(queries, (q) => +q.id === +queryIDToKill), - }); - - // kill the query over http - const {dataNodes, params} = this.props; - killQuery(dataNodes, queryIDToKill, params.clusterID).then(() => { - this.setState({ - queryIDToKill: null, - }); - }); - }, -}); - -export default QueriesPage; diff --git a/archive/queries/index.js b/archive/queries/index.js deleted file mode 100644 index ad08e50069..0000000000 --- a/archive/queries/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import QueriesPage from './containers/QueriesPage'; -export default QueriesPage; diff --git a/archive/retention_policies/components/CreateRetentionPolicyModal.js b/archive/retention_policies/components/CreateRetentionPolicyModal.js deleted file mode 100644 index 4c0cb451be..0000000000 --- a/archive/retention_policies/components/CreateRetentionPolicyModal.js +++ /dev/null @@ -1,70 +0,0 @@ -import React, {PropTypes} from 'react'; - -export default React.createClass({ - propTypes: { - onCreate: PropTypes.func.isRequired, - dataNodes: PropTypes.arrayOf(PropTypes.string).isRequired, - }, - - render() { - return ( - - ); - }, - - handleSubmit(e) { - e.preventDefault(); - const rpName = this.rpName.value; - const duration = this.duration.value; - const replicationFactor = this.replicationFactor.value; - - // Not using data-dimiss="modal" becuase it doesn't play well with HTML5 validations. - $('#rpModal').modal('hide'); // eslint-disable-line no-undef - - this.props.onCreate({ - rpName, - duration, - replicationFactor, - }); - }, -}); diff --git a/archive/retention_policies/components/DropShardModal.js b/archive/retention_policies/components/DropShardModal.js deleted file mode 100644 index 9e2fb0b740..0000000000 --- a/archive/retention_policies/components/DropShardModal.js +++ /dev/null @@ -1,74 +0,0 @@ -import React, {PropTypes} from 'react'; - -const DropShardModal = React.createClass({ - propTypes: { - onConfirm: PropTypes.func.isRequired, - }, - - getInitialState() { - return {error: null, text: ''}; - }, - - componentDidMount() { - // Using this unfortunate hack because this modal is still using bootstrap, - // and this component is never removed once being mounted -- meaning it doesn't - // start with a new initial state when it gets closed/reopened. A better - // long term solution is just to handle modals in ReactLand. - $('#dropShardModal').on('hide.bs.modal', () => { // eslint-disable-line no-undef - this.setState({error: null, text: ''}); - }); - }, - - handleConfirmationTextChange(e) { - this.setState({text: e.target.value}); - }, - - render() { - return ( - - ); - }, - - handleSubmit(e) { - e.preventDefault(); - - if (this.state.text.toLowerCase() !== 'delete') { - this.setState({error: "Please confirm by typing 'delete'"}); - return; - } - - // Hiding the modal directly because we have an extra confirmation step, - // bootstrap will close the modal immediately after clicking 'Delete'. - $('#dropShardModal').modal('hide'); // eslint-disable-line no-undef - - this.props.onConfirm(); - }, -}); - -export default DropShardModal; diff --git a/archive/retention_policies/components/RetentionPoliciesHeader.js b/archive/retention_policies/components/RetentionPoliciesHeader.js deleted file mode 100644 index b92c116f81..0000000000 --- a/archive/retention_policies/components/RetentionPoliciesHeader.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, {PropTypes} from 'react'; - -export default React.createClass({ - propTypes: { - databases: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types - selectedDatabase: PropTypes.string.isRequired, - onChooseDatabase: PropTypes.func.isRequired, - }, - - render() { - return ( -
-
-
-
- -
    - {this.props.databases.map((d) => { - return
  • this.props.onChooseDatabase(d)}>{d}
  • ; - })} -
-
-
-
- -
-
-
- ); - }, -}); diff --git a/archive/retention_policies/components/RetentionPoliciesList.js b/archive/retention_policies/components/RetentionPoliciesList.js deleted file mode 100644 index dcbb294863..0000000000 --- a/archive/retention_policies/components/RetentionPoliciesList.js +++ /dev/null @@ -1,63 +0,0 @@ -import React, {PropTypes} from 'react'; - -import RetentionPolicyCard from './RetentionPolicyCard'; - -const {string, arrayOf, shape, func} = PropTypes; -export default React.createClass({ - propTypes: { - retentionPolicies: arrayOf(shape()).isRequired, - shardDiskUsage: shape(), - shards: shape().isRequired, - selectedDatabase: string.isRequired, - onDropShard: func.isRequired, - }, - - render() { - const {shardDiskUsage, retentionPolicies, onDropShard, shards, selectedDatabase} = this.props; - - return ( -
-
-

Retention Policies

-
- {retentionPolicies.map((rp, i) => { - const ss = shards[`${selectedDatabase}..${rp.name}`] || []; - /** - * We use the `/show-shards` endpoint as 'source of truth' for active shards in the cluster. - * Disk usage has to be fetched directly from InfluxDB, which means we'll have stale shard - * data (the results will often include disk usage for shards that have been removed). This - * ensures we only use active shards when we calculate disk usage. - */ - const newDiskUsage = {}; - ss.forEach((shard) => { - (shardDiskUsage[shard.shardId] || []).forEach((d) => { - if (!shard.owners.map((o) => o.tcpAddr).includes(d.nodeID)) { - return; - } - - if (newDiskUsage[shard.shardId]) { - newDiskUsage[shard.shardId].push(d); - } else { - newDiskUsage[shard.shardId] = [d]; - } - }); - }); - - return ( - {}} - rp={rp} - shards={ss} - index={i} - shardDiskUsage={newDiskUsage} - onDropShard={onDropShard} - /> - ); - })} -
-
-
- ); - }, -}); diff --git a/archive/retention_policies/components/RetentionPolicyCard.js b/archive/retention_policies/components/RetentionPolicyCard.js deleted file mode 100644 index 8e8c9274e7..0000000000 --- a/archive/retention_policies/components/RetentionPolicyCard.js +++ /dev/null @@ -1,140 +0,0 @@ -import React, {PropTypes} from 'react'; -import classNames from 'classnames'; -import moment from 'moment'; - -import DropShardModal from './DropShardModal'; - -import {formatBytes, formatRPDuration} from 'utils/formatting'; - -/* eslint-disable no-magic-numbers */ - -const {func, string, shape, number, bool, arrayOf, objectOf} = PropTypes; -export default React.createClass({ - propTypes: { - onDropShard: func.isRequired, - rp: shape({ - name: string.isRequired, - duration: string.isRequired, - isDefault: bool.isRequired, - replication: number, - shardGroupDuration: string, - }).isRequired, - shards: arrayOf(shape({ - database: string.isRequired, - startTime: string.isRequired, - endTime: string.isRequired, - retentionPolicy: string.isRequired, - shardId: string.isRequired, - shardGroup: string.isRequired, - })), - shardDiskUsage: objectOf( - arrayOf( - shape({ - diskUsage: number.isRequired, - nodeID: string.isRequired, - }), - ), - ), - index: number, // Required to make bootstrap JS work. - }, - - formatTimestamp(timestamp) { - return moment(timestamp).format('YYYY-MM-DD:H'); - }, - - render() { - const {index, rp, shards, shardDiskUsage} = this.props; - - const diskUsage = shards.reduce((sum, shard) => { - // Check if we don't have any disk usage for a shard. This happens most often - // with a new cluster before any disk usage has a chance to be recorded. - if (!shardDiskUsage[shard.shardId]) { - return sum; - } - - return sum + shardDiskUsage[shard.shardId].reduce((shardSum, shardInfo) => { - return shardSum + shardInfo.diskUsage; - }, 0); - }, 0); - - return ( -
- -
-
- {this.renderShardTable()} -
-
- -
- ); - }, - - renderShardTable() { - const {shards, shardDiskUsage} = this.props; - - if (!shards.length) { - return
No shards.
; - } - - return ( - - - - - - - - - - - {shards.map((shard, index) => { - const diskUsages = shardDiskUsage[shard.shardId] || []; - return ( - - - - - - - - ); - })} - -
Shard IDTime RangeDisk UsageNodes -
{shard.shardId}{this.formatTimestamp(shard.startTime)} — {this.formatTimestamp(shard.endTime)} - {diskUsages.length ? diskUsages.map((s) => { - const diskUsageForShard = formatBytes(s.diskUsage) || 'n/a'; - return

{diskUsageForShard}

; - }) - : 'n/a'} -
- {diskUsages.length ? diskUsages.map((s) =>

{s.nodeID}

) : 'n/a'} -
- -
- ); - }, - - openConfirmationModal(shard) { - this.setState({shardIdToDelete: shard.shardId}); - }, - - handleDropShard() { - const shard = this.props.shards.filter((s) => s.shardId === this.state.shardIdToDelete)[0]; - this.props.onDropShard(shard); - this.setState({shardIdToDelete: null}); - }, -}); - -/* eslint-enable no-magic-numbers */ diff --git a/archive/retention_policies/containers/RetentionPoliciesApp.js b/archive/retention_policies/containers/RetentionPoliciesApp.js deleted file mode 100644 index 9d798a6464..0000000000 --- a/archive/retention_policies/containers/RetentionPoliciesApp.js +++ /dev/null @@ -1,212 +0,0 @@ -import React, {PropTypes} from 'react'; -import _ from 'lodash'; - -import RetentionPoliciesHeader from '../components/RetentionPoliciesHeader'; -import RetentionPoliciesList from '../components/RetentionPoliciesList'; -import CreateRetentionPolicyModal from '../components/CreateRetentionPolicyModal'; - -import { - showDatabases, - showRetentionPolicies, - showShards, - createRetentionPolicy, - dropShard, -} from 'shared/apis/metaQuery'; -import {fetchShardDiskBytesForDatabase} from 'shared/apis/stats'; -import parseShowDatabases from 'shared/parsing/showDatabases'; -import parseShowRetentionPolicies from 'shared/parsing/showRetentionPolicies'; -import parseShowShards from 'shared/parsing/showShards'; -import {diskBytesFromShardForDatabase} from 'shared/parsing/diskBytes'; - -const RetentionPoliciesApp = React.createClass({ - propTypes: { - dataNodes: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired, - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, - addFlashMessage: PropTypes.func, - }, - - getInitialState() { - return { - // Simple list of databases - databases: [], - - // A list of retention policy objects for the currently selected database - retentionPolicies: [], - - /** - * Disk usage/node locations for all shards across a database, keyed by shard ID. - * e.g. if shard 10 was replicated across two data nodes: - * { - * 10: [ - * {nodeID: 'localhost:8088', diskUsage: 12312414}, - * {nodeID: 'localhost:8188', diskUsage: 12312414}, - * ], - * ... - * } - */ - shardDiskUsage: {}, - - // All shards across all databases, keyed by database and retention policy. e.g.: - // 'telegraf..default': [ - // , - // - // ] - shards: {}, - - selectedDatabase: null, - isFetching: true, - }; - }, - - componentDidMount() { - showDatabases(this.props.dataNodes, this.props.params.clusterID).then((resp) => { - const result = parseShowDatabases(resp.data); - - if (!result.databases.length) { - this.props.addFlashMessage({ - text: 'No databases found', - type: 'error', - }); - - return; - } - - const selectedDatabase = result.databases[0]; - - this.setState({ - databases: result.databases, - selectedDatabase, - }); - - this.fetchInfoForDatabase(selectedDatabase); - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.addGenericErrorMessage(err.toString()); - }); - }, - - fetchInfoForDatabase(database) { - this.setState({isFetching: true}); - Promise.all([ - this.fetchRetentionPoliciesAndShards(database), - this.fetchDiskUsage(database), - ]).then(([rps, shardDiskUsage]) => { - const {retentionPolicies, shards} = rps; - this.setState({ - shardDiskUsage, - retentionPolicies, - shards, - }); - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.addGenericErrorMessage(err.toString()); - }).then(() => { - this.setState({isFetching: false}); - }); - }, - - addGenericErrorMessage(errMessage) { - const defaultMsg = 'Something went wrong! Try refreshing your browser and email support@influxdata.com if the problem persists.'; - this.props.addFlashMessage({ - text: errMessage || defaultMsg, - type: 'error', - }); - }, - - fetchRetentionPoliciesAndShards(database) { - const shared = {}; - return showRetentionPolicies(this.props.dataNodes, database, this.props.params.clusterID).then((resp) => { - shared.retentionPolicies = resp.data.results.map(parseShowRetentionPolicies); - return showShards(this.props.params.clusterID); - }).then((resp) => { - const shards = parseShowShards(resp.data); - return {shards, retentionPolicies: shared.retentionPolicies[0].retentionPolicies}; - }); - }, - - fetchDiskUsage(database) { - const {dataNodes, params: {clusterID}} = this.props; - return fetchShardDiskBytesForDatabase(dataNodes, database, clusterID).then((resp) => { - return diskBytesFromShardForDatabase(resp.data).shardData; - }); - }, - - handleChooseDatabase(database) { - this.setState({selectedDatabase: database, retentionPolicies: []}); - this.fetchInfoForDatabase(database); - }, - - handleCreateRetentionPolicy({rpName, duration, replicationFactor}) { - const params = { - database: this.state.selectedDatabase, - host: this.props.dataNodes, - rpName, - duration, - replicationFactor, - clusterID: this.props.params.clusterID, - }; - - createRetentionPolicy(params).then(() => { - this.props.addFlashMessage({ - text: 'Retention policy created successfully!', - type: 'success', - }); - this.fetchInfoForDatabase(this.state.selectedDatabase); - }).catch((err) => { - this.addGenericErrorMessage(err.toString()); - }); - }, - - render() { - if (this.state.isFetching) { - return
; - } - - const {selectedDatabase, shards, shardDiskUsage} = this.state; - - return ( -
- -
- -
- -
- ); - }, - - handleDropShard(shard) { - const {dataNodes, params} = this.props; - dropShard(dataNodes, shard, params.clusterID).then(() => { - const key = `${this.state.selectedDatabase}..${shard.retentionPolicy}`; - - const shardsForRP = this.state.shards[key]; - const nextShards = _.reject(shardsForRP, (s) => s.shardId === shard.shardId); - - const shards = Object.assign({}, this.state.shards); - shards[key] = nextShards; - - this.props.addFlashMessage({ - text: `Dropped shard ${shard.shardId}`, - type: 'success', - }); - this.setState({shards}); - }).catch(() => { - this.addGenericErrorMessage(); - }); - }, -}); - -export default RetentionPoliciesApp; diff --git a/archive/retention_policies/index.js b/archive/retention_policies/index.js deleted file mode 100644 index c63309f895..0000000000 --- a/archive/retention_policies/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import RetentionPoliciesApp from './containers/RetentionPoliciesApp'; -export default RetentionPoliciesApp; diff --git a/archive/sign_up/components/CreateClusterAdmin.js b/archive/sign_up/components/CreateClusterAdmin.js deleted file mode 100644 index e8fe2026ad..0000000000 --- a/archive/sign_up/components/CreateClusterAdmin.js +++ /dev/null @@ -1,79 +0,0 @@ -import React, {PropTypes} from 'react'; - -const CreateClusterAdmin = React.createClass({ - propTypes: { - onCreateClusterAdmin: PropTypes.func.isRequired, - }, - - getInitialState() { - return { - passwordsMatch: true, - }; - }, - - handleSubmit(e) { - e.preventDefault(); - const username = this.username.value; - const password = this.password.value; - const confirmation = this.confirmation.value; - - if (password !== confirmation) { - return this.setState({ - passwordsMatch: false, - }); - } - - this.props.onCreateClusterAdmin(username, password); - }, - - render() { - const {passwordsMatch} = this.state; - - return ( -
-
-
-
-
-
-
2/3
-

Welcome to InfluxEnterprise

-
-
- {passwordsMatch ? null : this.renderValidationError()} -

Create a Cluster Administrator account.

-

Users assigned to the Cluster Administrator account have all cluster permissions.

-
-
- - this.username = username} className="form-control input-lg" type="text" id="username" required={true} placeholder="Ex. ClusterAdmin"/> -
-
- - this.password = pass} className="form-control input-lg" type="password" id="password" required={true}/> -
-
- - this.confirmation = conf} className="form-control input-lg" type="password" id="confirmation" required={true} /> -
- - -
- -
-
-
-
-
-
-
-
- ); - }, - - renderValidationError() { - return
Your passwords don't match! Please make sure they match.
; - }, -}); - -export default CreateClusterAdmin; diff --git a/archive/sign_up/components/CreateWebAdmin.js b/archive/sign_up/components/CreateWebAdmin.js deleted file mode 100644 index 25cf03f798..0000000000 --- a/archive/sign_up/components/CreateWebAdmin.js +++ /dev/null @@ -1,125 +0,0 @@ -import React, {PropTypes} from 'react'; -import ClusterAccounts from 'shared/components/AddClusterAccounts'; -import {getClusters} from 'shared/apis'; - -const CreateWebAdmin = React.createClass({ - propTypes: { - onCreateWebAdmin: PropTypes.func.isRequired, - }, - - getInitialState() { - return { - clusters: [], - clusterLinks: {}, - passwordsMatch: true, - }; - }, - - 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; - const confirmation = this.confirmation.value; - - if (password !== confirmation) { - return this.setState({passwordsMatch: false}); - } - - this.props.onCreateWebAdmin(firstName, lastName, email, password, confirmation, this.getClusterLinks()); - }, - - handleSelectClusterAccount({clusterID, accountName}) { - const clusterLinks = Object.assign({}, this.state.clusterLinks, { - [clusterID]: accountName, - }); - this.setState({ - clusterLinks, - }); - }, - - getClusterLinks() { - return Object.keys(this.state.clusterLinks).map((clusterID) => { - return { - cluster_id: clusterID, - cluster_user: this.state.clusterLinks[clusterID], - }; - }); - }, - - render() { - const {clusters, passwordsMatch, clusterLinks} = this.state; - return ( -
-
-
-
-
-
-
3/3
-

Welcome to InfluxEnterprise

-
-
- {passwordsMatch ? null : this.renderValidationError()} -

Create a Web Administrator user.

-
A Web Administrator has all web console permissions.
-

- After filling out the form with your name, email, and password, assign yourself to the Cluster Administrator account that you - created in the previous step. This ensures that you have all web console permissions and all cluster permissions. -

-
-
-
- - this.firstName = firstName} className="form-control input-lg" type="text" id="first-name" required={true} /> -
-
- - this.lastName = lastName} className="form-control input-lg" type="text" id="last-name" required={true} /> -
-
-
-
- - this.email = email} className="form-control input-lg" type="text" id="email" required={true} /> -
-
-
-
- - this.password = password} className="form-control input-lg" type="password" id="password" required={true} /> -
-
- - this.confirmation = confirmation} className="form-control input-lg" type="password" id="confirmation" required={true} /> -
-
- - {clusters.length ? : null} - -
- -
- -
-
-
-
-
-
- ); - }, - - renderValidationError() { - return
Your passwords don't match!
; - }, -}); - -export default CreateWebAdmin; diff --git a/archive/sign_up/components/NameCluster.js b/archive/sign_up/components/NameCluster.js deleted file mode 100644 index 4ae9dd2b7f..0000000000 --- a/archive/sign_up/components/NameCluster.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, {PropTypes} from 'react'; - -const NameCluster = React.createClass({ - propTypes: { - onNameCluster: PropTypes.func.isRequired, - }, - - handleSubmit(e) { - e.preventDefault(); - this.props.onNameCluster(this.clusterName.value); - }, - - render() { - return ( -
-
-
-
-
-
-
1/3
-

Welcome to InfluxEnterprise

-

-

-
-
-
-
-

What do you want to call your cluster?

- - this.clusterName = name} className="form-control input-lg" type="text" id="cluster-name" placeholder="Ex. MyCluster"/> -
- -
- -
-
-
-
-
-
-
-
- ); - }, -}); - -export default NameCluster; diff --git a/archive/sign_up/components/NoCluster.js b/archive/sign_up/components/NoCluster.js deleted file mode 100644 index 223618b93d..0000000000 --- a/archive/sign_up/components/NoCluster.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; - -const NoCluster = React.createClass({ - handleSubmit() { - window.location.reload(); - }, - - render() { - return ( -
-
-
-
-
-
-

Welcome to Enterprise

-

- Looks like you don't have your cluster set up. -

-
-
- -
-
-
-
-
-
- ); - }, -}); - -export default NoCluster; diff --git a/archive/sign_up/index.js b/archive/sign_up/index.js deleted file mode 100644 index fc8ffa3335..0000000000 --- a/archive/sign_up/index.js +++ /dev/null @@ -1,97 +0,0 @@ -import React, {PropTypes} from 'react'; -import CreateClusterAdmin from './components/CreateClusterAdmin'; -import CreateWebAdmin from './components/CreateWebAdmin'; -import NameCluster from './components/NameCluster'; -import NoCluster from './components/NoCluster'; -import {withRouter} from 'react-router'; -import { - createWebAdmin, - getClusters, - createClusterUserAtSetup, - updateClusterAtSetup, -} from 'shared/apis'; - -const SignUpApp = React.createClass({ - propTypes: { - params: PropTypes.shape({ - step: PropTypes.string.isRequired, - }).isRequired, - router: PropTypes.shape({ - push: PropTypes.func.isRequired, - replace: PropTypes.func.isRequired, - }).isRequired, - }, - - getInitialState() { - return { - clusterDisplayName: null, - clusterIDs: null, - activeClusterID: null, - clusterUser: '', - }; - }, - - componentDidMount() { - getClusters().then(({data: clusters}) => { - const clusterIDs = clusters.map((c) => c.cluster_id); // TODO: handle when the first cluster is down... - this.setState({ - clusterIDs, - activeClusterID: clusterIDs[0], - }); - }); - }, - - handleNameCluster(clusterDisplayName) { - this.setState({clusterDisplayName}, () => { - this.props.router.replace('/signup/admin/2'); - }); - }, - - handleCreateClusterAdmin(username, password) { - const {activeClusterID, clusterDisplayName} = this.state; - createClusterUserAtSetup(activeClusterID, username, password).then(() => { - updateClusterAtSetup(activeClusterID, clusterDisplayName).then(() => { - this.setState({clusterUser: username}, () => { - this.props.router.replace('/signup/admin/3'); - }); - }); - }); - }, - - handleCreateWebAdmin(firstName, lastName, email, password, confirmation, clusterLinks) { - createWebAdmin({firstName, lastName, email, password, confirmation, clusterLinks}).then(() => { - window.location.replace('/'); - }); - }, - - render() { - const {params: {step}, router} = this.props; - const {clusterDisplayName, clusterIDs} = this.state; - - if (!['1', '2', '3'].includes(step)) { - router.replace('/signup/admin/1'); - } - - if (clusterIDs === null) { - return null; // spinner? - } - - if (!clusterIDs.length) { - return ; - } - - if (step === '1' || !clusterDisplayName) { - return ; - } - - if (step === '2') { - return ; - } - - if (step === '3') { - return ; - } - }, -}); - -export default withRouter(SignUpApp);