From 3a0b233d04fe93da58a117405bf840e729ed6520 Mon Sep 17 00:00:00 2001 From: Jade McGough Date: Mon, 19 Sep 2016 16:43:59 -0700 Subject: [PATCH] removing old API dependencies --- ui/src/App.js | 7 +- ui/src/CheckDataNodes.js | 9 +- .../containers/RolePageContainer.js | 2 +- ui/src/chronograf/actions/view/index.js | 8 +- .../containers/ClusterAccountContainer.js | 2 +- .../components/DatabaseManager.js | 7 +- ui/src/index.js | 128 ++++++++---------- ui/src/shared/apis/index.js | 26 ++-- ui/src/shared/apis/metaQuery.js | 4 +- ui/src/shared/components/RolePanels.js | 7 +- ui/src/side_nav/components/SideNav.js | 82 +++-------- ui/src/side_nav/containers/SideNavApp.js | 44 +----- ui/src/utils/queryUrlGenerator.js | 4 +- 13 files changed, 112 insertions(+), 218 deletions(-) diff --git a/ui/src/App.js b/ui/src/App.js index a142b463f..e0cd5e7d7 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -4,9 +4,6 @@ import SideNavContainer from 'src/side_nav'; const App = React.createClass({ propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, addFlashMessage: PropTypes.func.isRequired, // Injected by the `FlashMessages` wrapper children: PropTypes.node.isRequired, location: PropTypes.shape({ @@ -15,11 +12,9 @@ const App = React.createClass({ }, render() { - const {clusterID} = this.props.params; - return (
- +
{this.props.children && React.cloneElement(this.props.children, { addFlashMessage: this.props.addFlashMessage, diff --git a/ui/src/CheckDataNodes.js b/ui/src/CheckDataNodes.js index 7382c40aa..67db43453 100644 --- a/ui/src/CheckDataNodes.js +++ b/ui/src/CheckDataNodes.js @@ -2,16 +2,13 @@ import React, {PropTypes} from 'react'; import NoClusterError from 'shared/components/NoClusterError'; import NoClusterLinksError from 'shared/components/NoClusterLinksError'; import {webUserShape} from 'src/utils/propTypes'; -import {showCluster} from 'src/shared/apis'; +import {getSources} from 'src/shared/apis'; // Acts as a 'router middleware'. The main `App` component is responsible for // getting the list of data nodes, but not every page requires them to function. // Routes that do require data nodes can be nested under this component. const CheckDataNodes = React.createClass({ propTypes: { - params: PropTypes.shape({ - clusterID: PropTypes.string.isRequired, - }).isRequired, addFlashMessage: PropTypes.func, children: PropTypes.node, }, @@ -44,8 +41,8 @@ const CheckDataNodes = React.createClass({ }, componentDidMount() { - const {clusterID} = this.props.params; - showCluster(clusterID).then((resp) => { + getSources().then((resp) => { + // TODO: get this wired up correctly once getSources is working. const dataNodes = this.getHealthyDataNodes(resp.data.data); this.setState({ dataNodes, diff --git a/ui/src/access_control/containers/RolePageContainer.js b/ui/src/access_control/containers/RolePageContainer.js index ed79291c9..d83d3ae0e 100644 --- a/ui/src/access_control/containers/RolePageContainer.js +++ b/ui/src/access_control/containers/RolePageContainer.js @@ -104,7 +104,7 @@ export const RolePageContainer = React.createClass({ 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(`/clusters/${clusterID}/roles`); + this.props.router.push(`/roles`); }).catch(err => { console.error(err.toString()); // eslint-disable-line no-console this.addErrorNotification(err); diff --git a/ui/src/chronograf/actions/view/index.js b/ui/src/chronograf/actions/view/index.js index 0aa1dc0b8..da4a05183 100644 --- a/ui/src/chronograf/actions/view/index.js +++ b/ui/src/chronograf/actions/view/index.js @@ -158,7 +158,7 @@ export function createExplorer(clusterID, push) { }).then((resp) => { const explorer = parseRawExplorer(resp.data); dispatch(loadExplorer(explorer)); - push(`/clusters/${clusterID}/chronograf/data_explorer/${explorer.id}`); + push(`/chronograf/data_explorer/${explorer.id}`); }); }; } @@ -179,7 +179,7 @@ export function deleteExplorer(clusterID, explorerID, push) { // explorer and should create a new one. if (explorer) { dispatch(loadExplorer(explorer)); - push(`/clusters/${clusterID}/chronograf/data_explorer/${explorer.id}`); + push(`/chronograf/data_explorer/${explorer.id}`); } else { dispatch(createExplorer(clusterID, push)); } @@ -249,7 +249,7 @@ export function fetchExplorers({clusterID, explorerID, push}) { if (!explorerID) { const explorer = _.maxBy(explorers, (ex) => ex.updated_at); dispatch(loadExplorer(explorer)); - push(`/clusters/${clusterID}/chronograf/data_explorer/${explorer.id}`); + push(`/chronograf/data_explorer/${explorer.id}`); return; } @@ -306,7 +306,7 @@ export function chooseExplorer(clusterID, explorerID, push) { }).then((resp) => { const explorer = parseRawExplorer(resp.data); dispatch(loadExplorer(explorer)); - push(`/clusters/${clusterID}/chronograf/data_explorer/${explorerID}`); + push(`/chronograf/data_explorer/${explorerID}`); }); }; } diff --git a/ui/src/cluster_accounts/containers/ClusterAccountContainer.js b/ui/src/cluster_accounts/containers/ClusterAccountContainer.js index 441dd4f51..e0bb9b98b 100644 --- a/ui/src/cluster_accounts/containers/ClusterAccountContainer.js +++ b/ui/src/cluster_accounts/containers/ClusterAccountContainer.js @@ -235,7 +235,7 @@ export const ClusterAccountContainer = React.createClass({ handleDeleteAccount() { const {clusterID, accountID} = this.props.params; deleteClusterAccount(clusterID, accountID).then(() => { - this.props.router.push(`/clusters/${clusterID}/accounts`); + this.props.router.push(`/accounts`); this.props.addFlashMessage({ type: 'success', text: 'Cluster account deleted!', diff --git a/ui/src/database_manager/components/DatabaseManager.js b/ui/src/database_manager/components/DatabaseManager.js index 02f39e4ea..0b4870862 100644 --- a/ui/src/database_manager/components/DatabaseManager.js +++ b/ui/src/database_manager/components/DatabaseManager.js @@ -8,7 +8,6 @@ const {number, string, shape, arrayOf, func} = PropTypes; const DatabaseManager = React.createClass({ propTypes: { - clusterID: string.isRequired, database: string.isRequired, databases: arrayOf(shape({})).isRequired, dbStats: shape({ @@ -24,7 +23,7 @@ const DatabaseManager = React.createClass({ }, render() { - const {database, clusterID, databases, dbStats, queries, users, + const {database, databases, dbStats, queries, users, replicationFactors, onClickDatabase, onCreateDatabase} = this.props; return ( @@ -40,7 +39,7 @@ const DatabaseManager = React.createClass({
    { databases.map((db) => { - return
  • onClickDatabase(db.Name)} key={db.Name}>{db.Name}
  • ; + return
  • onClickDatabase(db.Name)} key={db.Name}>{db.Name}
  • ; }) }
@@ -96,7 +95,7 @@ const DatabaseManager = React.createClass({ users.map((user) => { return ( - {user.name} + {user.name} {user.roles} ); diff --git a/ui/src/index.js b/ui/src/index.js index 1dcbbe021..5b6f4b6ed 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -1,4 +1,4 @@ -import React, {PropTypes} from 'react'; +import React from 'react'; import {render} from 'react-dom'; import {Provider} from 'react-redux'; import {Router, Route, browserHistory} from 'react-router'; @@ -17,18 +17,12 @@ 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 InsufficientPermissions from 'src/shared/components/InsufficientPermissions'; import NoClusterError from 'src/shared/components/NoClusterError'; import configureStore from 'src/store/configureStore'; import {webUserShape} from 'src/utils/propTypes'; -import {meShow, getClusterAccount, getRoles} from 'shared/apis'; -import {buildClusterAccounts} from 'src/shared/presenters'; import 'src/style/enterprise_style/application.scss'; -const VIEW_CHRONOGRAF = 'ViewChronograf'; -const READ = 'ReadData'; - const defaultTimeRange = {upper: null, lower: 'now() - 15m'}; const lsTimeRange = window.localStorage.getItem('timeRange'); const parsedTimeRange = JSON.parse(lsTimeRange) || {}; @@ -37,85 +31,75 @@ const timeRange = Object.assign(defaultTimeRange, parsedTimeRange); const store = configureStore({timeRange}); const rootNode = document.getElementById('react-root'); -function hasPermission(account, permission) { - const hasNakedPermission = !!account.permissions.find(p => p.name === permission); - const hasPermissionInRole = account.roles.some((role) => { - return role.permissions.some(p => p.name === permission); - }); - - return hasNakedPermission || hasPermissionInRole; -} - const HTTP_SERVER_ERROR = 500; const Root = React.createClass({ getInitialState() { return { - me: null, - canViewChronograf: false, - isFetching: true, + me: { + id: 1, + name: 'MrFusion', + email: 'foo@example.com', + admin: true, + }, + isFetching: false, hasReadPermission: false, clusterStatus: null, }; }, componentDidMount() { - meShow().then(({data: me}) => { - const match = window.location.pathname.match(/\/clusters\/(\d*)/); - const clusterID = match && match[1]; - const clusterLink = me.cluster_links.find(link => link.cluster_id === clusterID); - if (clusterLink) { - Promise.all([ - getClusterAccount(clusterID, clusterLink.cluster_user), - getRoles(clusterID), - ]).then(([{data: {users}}, {data: {roles}}]) => { - const account = buildClusterAccounts(users, roles)[0]; - const canViewChronograf = hasPermission(account, VIEW_CHRONOGRAF); - const hasReadPermission = hasPermission(account, READ); - this.setState({ - me, - canViewChronograf, - isFetching: false, - hasReadPermission, - }); - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.setState({ - canViewChronograf: false, - isFetching: false, - clusterStatus: err.response.status, - }); - }); - } else { - this.setState({ - me, - isFetching: false, - }); - } - }).catch((err) => { - console.error(err); // eslint-disable-line no-console - this.setState({ - isFetching: false, - }); - }); + // meShow().then(({data: me}) => { + // const match = window.location.pathname.match(/\/clusters\/(\d*)/); + // const clusterID = match && match[1]; + // const clusterLink = me.cluster_links.find(link => link.cluster_id === clusterID); + // if (clusterLink) { + // Promise.all([ + // getClusterAccount(clusterID, clusterLink.cluster_user), + // getRoles(clusterID), + // ]).then(([{data: {users}}, {data: {roles}}]) => { + // const account = buildClusterAccounts(users, roles)[0]; + // const canViewChronograf = hasPermission(account, VIEW_CHRONOGRAF); + // const hasReadPermission = hasPermission(account, READ); + // this.setState({ + // me, + // canViewChronograf, + // isFetching: false, + // hasReadPermission, + // }); + // }).catch((err) => { + // console.error(err); // eslint-disable-line no-console + // this.setState({ + // canViewChronograf: false, + // isFetching: false, + // clusterStatus: err.response.status, + // }); + // }); + // } else { + // this.setState({ + // me, + // isFetching: false, + // }); + // } + // }).catch((err) => { + // console.error(err); // eslint-disable-line no-console + // this.setState({ + // isFetching: false, + // }); + // }); }, childContextTypes: { me: webUserShape, - canViewChronograf: PropTypes.bool, }, getChildContext() { return { me: this.state.me, - canViewChronograf: this.state.canViewChronograf, }; }, render() { - const {me, canViewChronograf} = this.state; - const isAdmin = me && me.admin; - if (this.state.isFetching) { return null; } @@ -124,29 +108,25 @@ const Root = React.createClass({ return ; } - if (me && !this.state.hasReadPermission) { - return ; - } - return ( - + - {isAdmin ? : null} - {isAdmin ? : null} - {isAdmin ? : null} + + + - {canViewChronograf ? : null} - {canViewChronograf ? : null} + + - {isAdmin ? : null} - {isAdmin ? : null} + + diff --git a/ui/src/shared/apis/index.js b/ui/src/shared/apis/index.js index 2c547b5ff..c3ed9407b 100644 --- a/ui/src/shared/apis/index.js +++ b/ui/src/shared/apis/index.js @@ -1,8 +1,8 @@ import AJAX from 'utils/ajax'; -export function showCluster(clusterID) { +export function getSources() { return AJAX({ - url: metaProxy(clusterID, '/show-cluster'), + url: '/chronograf/v1/sources', }); } @@ -39,7 +39,7 @@ export function createDatabase({database, rpName, duration, replicaN}) { export function getClusters() { return AJAX({ - url: `/api/int/v1/clusters`, + url: ``, }); } @@ -64,9 +64,9 @@ export function meUpdate({firstName, lastName, email, password, confirmation, ol }); } -export function getWebUsers(clusterID) { +export function getWebUsers() { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/users`, + url: `/api/int/v1/users`, }); } @@ -242,7 +242,7 @@ export function deleteClusterAccount(clusterID, accountName) { }), // Remove any cluster user links that are tied to this cluster account. AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links/batch/${accountName}`, + url: `/api/int/v1/user_links/batch/${accountName}`, method: 'DELETE', }), ]); @@ -383,20 +383,20 @@ export function deleteRole(clusterID, roleName) { export function deleteUserClusterLink(clusterID, userClusterLinkID) { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links/${userClusterLinkID}`, + url: `/api/int/v1/user_links/${userClusterLinkID}`, method: `DELETE`, }); } -export function getUserClusterLinks(clusterID) { +export function getUserClusterLinks() { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links`, + url: `/api/int/v1/user_links`, }); } export function createUserClusterLink({userID, clusterID, clusterUser}) { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links`, + url: `/api/int/v1/user_links`, method: 'POST', data: { user_id: userID, @@ -408,7 +408,7 @@ export function createUserClusterLink({userID, clusterID, clusterUser}) { export function getWebUsersByClusterAccount(clusterID, clusterAccount) { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links/batch/${encodeURIComponent(clusterAccount)}`, + url: `/api/int/v1/user_links/batch/${encodeURIComponent(clusterAccount)}`, }); } @@ -422,12 +422,12 @@ export function batchCreateUserClusterLink(userID, clusterLinks) { export function addWebUsersToClusterAccount(clusterID, clusterAccount, userIDs) { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/user_links/batch/${encodeURIComponent(clusterAccount)}`, + url: `/api/int/v1/user_links/batch/${encodeURIComponent(clusterAccount)}`, method: 'POST', data: userIDs, }); } function metaProxy(clusterID, slug) { - return `/api/int/v1/clusters/${clusterID}/meta${slug}`; + return `/api/int/v1/meta${slug}`; } diff --git a/ui/src/shared/apis/metaQuery.js b/ui/src/shared/apis/metaQuery.js index 211ecb994..7e745105e 100644 --- a/ui/src/shared/apis/metaQuery.js +++ b/ui/src/shared/apis/metaQuery.js @@ -42,9 +42,9 @@ export function showRetentionPolicies(host, databases, clusterID) { return proxy(url, clusterID); } -export function showShards(clusterID) { +export function showShards() { return AJAX({ - url: `/api/int/v1/clusters/${clusterID}/show-shards`, + url: `/api/int/v1/show-shards`, }); } diff --git a/ui/src/shared/components/RolePanels.js b/ui/src/shared/components/RolePanels.js index 8ece91f13..b0913e050 100644 --- a/ui/src/shared/components/RolePanels.js +++ b/ui/src/shared/components/RolePanels.js @@ -3,11 +3,10 @@ import {Link} from 'react-router'; import PermissionsTable from 'src/shared/components/PermissionsTable'; import {roleShape} from 'utils/propTypes'; -const {arrayOf, string, bool, func} = PropTypes; +const {arrayOf, bool, func} = PropTypes; const RolePanels = React.createClass({ propTypes: { roles: arrayOf(roleShape).isRequired, - clusterID: string.isRequired, showUserCount: bool, onRemoveAccountFromRole: func, }, @@ -19,7 +18,7 @@ const RolePanels = React.createClass({ }, render() { - const {roles, clusterID} = this.props; + const {roles} = this.props; if (!roles.length) { return ( @@ -58,7 +57,7 @@ const RolePanels = React.createClass({ Remove ) : null} - + Go To Role
diff --git a/ui/src/side_nav/components/SideNav.js b/ui/src/side_nav/components/SideNav.js index 5d6d0a19f..638cf03df 100644 --- a/ui/src/side_nav/components/SideNav.js +++ b/ui/src/side_nav/components/SideNav.js @@ -1,81 +1,43 @@ import React, {PropTypes} from 'react'; -import RenameClusterModal from '../modals/RenameCluster'; import {NavBar, NavBlock, NavHeader, NavListItem} from 'src/side_nav/components/NavItems'; -const {func, string, arrayOf, shape, bool} = PropTypes; +const {string} = PropTypes; const SideNav = React.createClass({ propTypes: { - isAdmin: bool.isRequired, - canViewChronograf: bool.isRequired, - clusterID: string.isRequired, location: string.isRequired, - onRenameCluster: func.isRequired, - onOpenRenameModal: func.isRequired, - clusters: arrayOf(shape()).isRequired, - }, - - handleOpenRenameModal(clusterID) { - this.props.onOpenRenameModal(clusterID); }, render() { - const {clusterID, location, onRenameCluster, clusters, isAdmin, canViewChronograf} = this.props; + const {location} = this.props; return (
- { - isAdmin ? - - - Users - - : null - } - - - Overview - Queries - Tasks - Roles - {isAdmin ? Cluster Accounts : null} - {isAdmin ? Database Manager : null} - Retention Policies + + + Users - { - canViewChronograf ? - - - Data Explorer - - : null - } - - - Settings + + + Overview + Queries + Tasks + Roles + Cluster Accounts + Database Manager + Retention Policies + + + + Data Explorer + + + + Settings Logout - - { - clusters.map(({cluster_id: id, display_name: displayName}, i) => { - return ( - - {displayName || id} - { - isAdmin ? - - : null - } - - ); - }) - } - - {isAdmin ? : null}
); }, diff --git a/ui/src/side_nav/containers/SideNavApp.js b/ui/src/side_nav/containers/SideNavApp.js index 951c32f02..55c760aa8 100644 --- a/ui/src/side_nav/containers/SideNavApp.js +++ b/ui/src/side_nav/containers/SideNavApp.js @@ -1,18 +1,14 @@ import React, {PropTypes} from 'react'; -import {getClusters, updateCluster} from 'shared/apis'; import SideNav from '../components/SideNav'; -import {webUserShape} from 'src/utils/propTypes'; const {func, string} = PropTypes; const SideNavApp = React.createClass({ propTypes: { - clusterID: string.isRequired, currentLocation: string.isRequired, addFlashMessage: func.isRequired, }, contextTypes: { - me: webUserShape, canViewChronograf: PropTypes.bool, }, @@ -23,49 +19,15 @@ const SideNavApp = React.createClass({ }; }, - getPageData() { - getClusters().then(({data: clusters}) => { - this.setState({clusters}); - }); - }, - - componentDidMount() { - this.getPageData(); - }, - - handleRenameCluster(displayName) { - const {addFlashMessage} = this.props; - updateCluster(this.state.clusterToUpdate, displayName).then(() => { - this.getPageData(); - addFlashMessage({ - type: 'success', - text: 'Cluster name changed successully', - }); - }).catch(() => { - addFlashMessage({ - type: 'error', - text: 'Something went wrong while renaming the cluster', - }); - }); - }, - - handleOpenRenameModal(clusterToUpdate) { - this.setState({clusterToUpdate}); - }, - render() { - const {clusterID, currentLocation} = this.props; - const {me, canViewChronograf} = this.context; + const {currentLocation} = this.props; + const {canViewChronograf} = this.context; return ( ); }, diff --git a/ui/src/utils/queryUrlGenerator.js b/ui/src/utils/queryUrlGenerator.js index 194cd4ab8..a7af1572f 100644 --- a/ui/src/utils/queryUrlGenerator.js +++ b/ui/src/utils/queryUrlGenerator.js @@ -18,9 +18,9 @@ export function buildInfluxUrl({host, statement, database, retentionPolicy}) { return encodeURIComponent(url); } -export function proxy(url, clusterID) { +export function proxy(url) { return AJAX({ - url: `/clusters/${clusterID}/proxy?proxy_url=${url}`, + url: `/proxy?proxy_url=${url}`, }); }