Fetch live data from /chronograf/v1/users & load into Chronograf Admin Table
Move DUMMY_USERS data into admin/chronograf/loadUsers spec. This adds a full roundtrip for populating the Chronograf Admin Table with live data from the server. It includes a reducer & test, action creator, and API request, which then loads the successful data into the Redux and then the React component.remotes/origin/multitenancy_temp_stash
parent
0376dc32b7
commit
616e4bbb98
|
@ -0,0 +1,176 @@
|
|||
import reducer from 'src/admin/reducers/chronograf'
|
||||
|
||||
import {loadUsers} from 'src/admin/actions/chronograf'
|
||||
|
||||
let state
|
||||
|
||||
const users = [
|
||||
{
|
||||
id: 666,
|
||||
name: 'bob@billietta.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'admin'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/666'},
|
||||
},
|
||||
{
|
||||
id: 667,
|
||||
name: 'billybob@gmail.com',
|
||||
provider: 'Auth0',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'viewer'},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/667'},
|
||||
},
|
||||
{
|
||||
id: 720,
|
||||
name: 'shorty@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/720'},
|
||||
},
|
||||
{
|
||||
id: 271,
|
||||
name: 'shawn.ofthe.dead@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/271'},
|
||||
},
|
||||
{
|
||||
id: 6389,
|
||||
name: 'swogglez@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'viewer'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'viewer'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/6389'},
|
||||
},
|
||||
{
|
||||
id: 99181,
|
||||
name: 'whiskey.elbow@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'viewer'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'viewer'},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'viewer'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/99181'},
|
||||
},
|
||||
{
|
||||
id: 3786,
|
||||
name: 'bob.builder@gmail.com',
|
||||
provider: 'Generic',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/3786'},
|
||||
},
|
||||
{
|
||||
id: 112345,
|
||||
name: 'lost.in.translation@gmail.com',
|
||||
provider: 'Generic',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/112345'},
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
name: 'wandering.soul@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/23'},
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'disembodied@gmail.com',
|
||||
provider: 'Auth0',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/7'},
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
name: 'bob.builder@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/0'},
|
||||
},
|
||||
{
|
||||
id: 2891,
|
||||
name: 'swag.bandit@gmail.com',
|
||||
provider: 'Google',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1234, name: 'admin'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/2891'},
|
||||
},
|
||||
{
|
||||
id: 2645,
|
||||
name: 'lord.ofthe.dance@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
superadmin: true,
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/2645'},
|
||||
},
|
||||
{
|
||||
id: 47119,
|
||||
name: 'ohnooeezzz@gmail.com',
|
||||
provider: 'Google',
|
||||
scheme: 'OAuth2',
|
||||
superadmin: true,
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1234, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/47119'},
|
||||
},
|
||||
]
|
||||
|
||||
describe('Admin.Chronograf.Reducers', () => {
|
||||
it('it can load all users', () => {
|
||||
const actual = reducer(state, loadUsers({users}))
|
||||
const expected = {
|
||||
users,
|
||||
}
|
||||
|
||||
expect(actual.users).to.deep.equal(expected.users)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,23 @@
|
|||
import {getUsers as getUsersAJAX} from 'src/admin/apis/chronograf'
|
||||
|
||||
import {errorThrown} from 'shared/actions/errors'
|
||||
|
||||
// action creators
|
||||
|
||||
// response contains `users` and `links`
|
||||
export const loadUsers = ({users}) => ({
|
||||
type: 'CHRONOGRAF_LOAD_USERS',
|
||||
payload: {
|
||||
users,
|
||||
},
|
||||
})
|
||||
|
||||
// async actions (thunks)
|
||||
export const loadUsersAsync = url => async dispatch => {
|
||||
try {
|
||||
const {data} = await getUsersAJAX(url)
|
||||
dispatch(loadUsers(data))
|
||||
} catch (error) {
|
||||
dispatch(errorThrown(error))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import AJAX from 'src/utils/ajax'
|
||||
|
||||
export const getUsers = async url => {
|
||||
try {
|
||||
return await AJAX({
|
||||
method: 'GET',
|
||||
url,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
|
@ -1,165 +1,5 @@
|
|||
export const NO_ROLE = 'No Role'
|
||||
|
||||
export const DUMMY_USERS = [
|
||||
{
|
||||
id: 666,
|
||||
name: 'bob@billietta.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'admin'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/666'},
|
||||
},
|
||||
{
|
||||
id: 667,
|
||||
name: 'billybob@gmail.com',
|
||||
provider: 'Auth0',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'viewer'},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/667'},
|
||||
},
|
||||
{
|
||||
id: 720,
|
||||
name: 'shorty@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/720'},
|
||||
},
|
||||
{
|
||||
id: 271,
|
||||
name: 'shawn.ofthe.dead@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/271'},
|
||||
},
|
||||
{
|
||||
id: 6389,
|
||||
name: 'swogglez@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'viewer'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'viewer'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/6389'},
|
||||
},
|
||||
{
|
||||
id: 99181,
|
||||
name: 'whiskey.elbow@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Green Team', organizationID: 1234, name: 'viewer'},
|
||||
{organizationName: 'Blue Team', organizationID: 1235, name: 'viewer'},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'viewer'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/99181'},
|
||||
},
|
||||
{
|
||||
id: 3786,
|
||||
name: 'bob.builder@gmail.com',
|
||||
provider: 'Generic',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/3786'},
|
||||
},
|
||||
{
|
||||
id: 112345,
|
||||
name: 'lost.in.translation@gmail.com',
|
||||
provider: 'Generic',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/112345'},
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
name: 'wandering.soul@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/23'},
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'disembodied@gmail.com',
|
||||
provider: 'Auth0',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/7'},
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
name: 'bob.builder@gmail.com',
|
||||
provider: 'Heroku',
|
||||
scheme: 'LDAP',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Red Team', organizationID: 1236, name: 'editor'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/0'},
|
||||
},
|
||||
{
|
||||
id: 2891,
|
||||
name: 'swag.bandit@gmail.com',
|
||||
provider: 'Google',
|
||||
scheme: 'OAuth2',
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1234, name: 'admin'},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/2891'},
|
||||
},
|
||||
{
|
||||
id: 2645,
|
||||
name: 'lord.ofthe.dance@gmail.com',
|
||||
provider: 'GitHub',
|
||||
scheme: 'OAuth2',
|
||||
superadmin: true,
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/2645'},
|
||||
},
|
||||
{
|
||||
id: 47119,
|
||||
name: 'ohnooeezzz@gmail.com',
|
||||
provider: 'Google',
|
||||
scheme: 'OAuth2',
|
||||
superadmin: true,
|
||||
roles: [
|
||||
{organizationName: 'All Users', organizationID: 666, name: NO_ROLE},
|
||||
{organizationName: 'Blue Team', organizationID: 1234, name: NO_ROLE},
|
||||
],
|
||||
links: {self: '/chronograf/v1/users/47119'},
|
||||
},
|
||||
]
|
||||
|
||||
export const USER_ROLES = [
|
||||
{name: NO_ROLE},
|
||||
{name: 'viewer'},
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import React, {Component, PropTypes} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import {loadUsersAsync} from 'src/admin/actions/chronograf'
|
||||
|
||||
import PageHeader from 'src/admin/components/chronograf/PageHeader'
|
||||
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
||||
|
@ -8,12 +12,7 @@ import CreateOrgOverlay from 'src/admin/components/chronograf/CreateOrgOverlay'
|
|||
|
||||
import FancyScrollbar from 'shared/components/FancyScrollbar'
|
||||
|
||||
import {
|
||||
DUMMY_USERS,
|
||||
DUMMY_ORGS,
|
||||
DEFAULT_ORG,
|
||||
NO_ORG,
|
||||
} from 'src/admin/constants/dummyUsers'
|
||||
import {DUMMY_ORGS, DEFAULT_ORG, NO_ORG} from 'src/admin/constants/dummyUsers'
|
||||
|
||||
class AdminChronografPage extends Component {
|
||||
constructor(props) {
|
||||
|
@ -28,6 +27,14 @@ class AdminChronografPage extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {loadUsers} = this.props
|
||||
|
||||
// TODO: determine this url from server
|
||||
const urlThatsProbablySourceLinksUsersChronograf = '/chronograf/v1/users'
|
||||
loadUsers(urlThatsProbablySourceLinksUsersChronograf)
|
||||
}
|
||||
|
||||
isSameUser = (userA, userB) => {
|
||||
return (
|
||||
userA.name === userB.name &&
|
||||
|
@ -106,7 +113,9 @@ class AdminChronografPage extends Component {
|
|||
filteredUsers,
|
||||
showCreateOverlay,
|
||||
} = this.state
|
||||
|
||||
const numUsersSelected = Object.keys(selectedUsers).length
|
||||
|
||||
return (
|
||||
<div className="page">
|
||||
<PageHeader onShowCreateOrgOverlay={this.handleShowCreateOrgOverlay} />
|
||||
|
@ -132,7 +141,7 @@ class AdminChronografPage extends Component {
|
|||
/>
|
||||
<div className="panel-body chronograf-admin-table--panel">
|
||||
<UsersTable
|
||||
filteredUsers={filteredUsers}
|
||||
filteredUsers={filteredUsers} // TODO: change to users upon separating Orgs & Users views
|
||||
organizationName={organizationName}
|
||||
onFilterUsers={this.handleFilterUsers}
|
||||
onToggleUserSelected={this.handleToggleUserSelected}
|
||||
|
@ -161,16 +170,24 @@ class AdminChronografPage extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const {arrayOf, shape} = PropTypes
|
||||
const {arrayOf, func, shape} = PropTypes
|
||||
|
||||
AdminChronografPage.propTypes = {
|
||||
users: arrayOf(shape),
|
||||
organizations: arrayOf(shape),
|
||||
loadUsers: func.isRequired,
|
||||
}
|
||||
|
||||
AdminChronografPage.defaultProps = {
|
||||
users: DUMMY_USERS,
|
||||
organizations: DUMMY_ORGS,
|
||||
}
|
||||
|
||||
export default AdminChronografPage
|
||||
const mapStateToProps = ({adminChronograf: {users}}) => ({
|
||||
users,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
loadUsers: bindActionCreators(loadUsersAsync, dispatch),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AdminChronografPage)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
const initialState = {
|
||||
users: [],
|
||||
organizations: [],
|
||||
}
|
||||
|
||||
const adminChronograf = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'CHRONOGRAF_LOAD_USERS': {
|
||||
return {...state, ...action.payload}
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
export default adminChronograf
|
|
@ -1,3 +1,4 @@
|
|||
import adminChronograf from './chronograf'
|
||||
import adminInfluxDB from './influxdb'
|
||||
|
||||
export default {adminInfluxDB}
|
||||
export default {adminChronograf, adminInfluxDB}
|
||||
|
|
Loading…
Reference in New Issue