Merge pull request #3001 from influxdata/chore/chronograf-admin-ts
Conversion of AllUsersPage to TypeScript add initial testpull/2999/merge
commit
458475243e
|
@ -1,15 +1,44 @@
|
||||||
import React, {Component} from 'react'
|
import React, {PureComponent} from 'react'
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import {connect} from 'react-redux'
|
import {connect} from 'react-redux'
|
||||||
import {bindActionCreators} from 'redux'
|
import {bindActionCreators} from 'redux'
|
||||||
|
|
||||||
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
|
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
|
||||||
import * as configActionCreators from 'shared/actions/config'
|
import * as configActionCreators from 'src/shared/actions/config'
|
||||||
import {notify as notifyAction} from 'shared/actions/notifications'
|
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||||
|
|
||||||
import AllUsersTable from 'src/admin/components/chronograf/AllUsersTable'
|
import AllUsersTable from 'src/admin/components/chronograf/AllUsersTable'
|
||||||
|
import {AuthLinks, User, Role, Organization} from 'src/types'
|
||||||
|
|
||||||
class AllUsersPage extends Component {
|
interface Props {
|
||||||
|
notify: () => void
|
||||||
|
links: AuthLinks
|
||||||
|
meID: string
|
||||||
|
users: User[]
|
||||||
|
organizations: Organization[]
|
||||||
|
actionsAdmin: {
|
||||||
|
loadUsersAsync: (link: string) => void
|
||||||
|
loadOrganizationsAsync: (link: string) => void
|
||||||
|
createUserAsync: (link: string, user: User) => void
|
||||||
|
updateUserAsync: (user: User, updatedUser: User, message: string) => void
|
||||||
|
deleteUserAsync: (
|
||||||
|
user: User,
|
||||||
|
deleteObj: {isAbsoluteDelete: boolean}
|
||||||
|
) => void
|
||||||
|
}
|
||||||
|
actionsConfig: {
|
||||||
|
getAuthConfigAsync: (link: string) => void
|
||||||
|
updateAuthConfigAsync: () => void
|
||||||
|
}
|
||||||
|
authConfig: {
|
||||||
|
superAdminNewUsers: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
isLoading: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AllUsersPage extends PureComponent<Props, State> {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
|
@ -23,32 +52,6 @@ class AllUsersPage extends Component {
|
||||||
getAuthConfigAsync(links.config.auth)
|
getAuthConfigAsync(links.config.auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCreateUser = user => {
|
|
||||||
const {links, actionsAdmin: {createUserAsync}} = this.props
|
|
||||||
createUserAsync(links.allUsers, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUpdateUserRoles = (user, roles, successMessage) => {
|
|
||||||
const {actionsAdmin: {updateUserAsync}} = this.props
|
|
||||||
const updatedUser = {...user, roles}
|
|
||||||
updateUserAsync(user, updatedUser, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUpdateUserSuperAdmin = (user, superAdmin) => {
|
|
||||||
const {actionsAdmin: {updateUserAsync}} = this.props
|
|
||||||
const updatedUser = {...user, superAdmin}
|
|
||||||
updateUserAsync(
|
|
||||||
user,
|
|
||||||
updatedUser,
|
|
||||||
`${user.name}'s SuperAdmin status has been updated`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteUser = user => {
|
|
||||||
const {actionsAdmin: {deleteUserAsync}} = this.props
|
|
||||||
deleteUserAsync(user, {isAbsoluteDelete: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
async componentWillMount() {
|
async componentWillMount() {
|
||||||
const {
|
const {
|
||||||
links,
|
links,
|
||||||
|
@ -65,65 +68,66 @@ class AllUsersPage extends Component {
|
||||||
this.setState({isLoading: false})
|
this.setState({isLoading: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCreateUser = (user: User) => {
|
||||||
|
const {links, actionsAdmin: {createUserAsync}} = this.props
|
||||||
|
createUserAsync(links.allUsers, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateUserRoles = (
|
||||||
|
user: User,
|
||||||
|
roles: Role[],
|
||||||
|
successMessage: string
|
||||||
|
) => {
|
||||||
|
const {actionsAdmin: {updateUserAsync}} = this.props
|
||||||
|
const updatedUser = {...user, roles}
|
||||||
|
updateUserAsync(user, updatedUser, successMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateUserSuperAdmin = (user: User, superAdmin: boolean) => {
|
||||||
|
const {actionsAdmin: {updateUserAsync}} = this.props
|
||||||
|
const updatedUser = {...user, superAdmin}
|
||||||
|
updateUserAsync(
|
||||||
|
user,
|
||||||
|
updatedUser,
|
||||||
|
`${user.name}'s SuperAdmin status has been updated`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDeleteUser = (user: User) => {
|
||||||
|
const {actionsAdmin: {deleteUserAsync}} = this.props
|
||||||
|
deleteUserAsync(user, {isAbsoluteDelete: true})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
organizations,
|
|
||||||
meID,
|
meID,
|
||||||
users,
|
users,
|
||||||
authConfig,
|
|
||||||
actionsConfig,
|
|
||||||
links,
|
links,
|
||||||
notify,
|
notify,
|
||||||
|
authConfig,
|
||||||
|
actionsConfig,
|
||||||
|
organizations,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AllUsersTable
|
<AllUsersTable
|
||||||
meID={meID}
|
meID={meID}
|
||||||
users={users}
|
users={users}
|
||||||
|
links={links}
|
||||||
|
notify={notify}
|
||||||
|
authConfig={authConfig}
|
||||||
|
actionsConfig={actionsConfig}
|
||||||
organizations={organizations}
|
organizations={organizations}
|
||||||
|
isLoading={this.state.isLoading}
|
||||||
|
onDeleteUser={this.handleDeleteUser}
|
||||||
onCreateUser={this.handleCreateUser}
|
onCreateUser={this.handleCreateUser}
|
||||||
onUpdateUserRoles={this.handleUpdateUserRoles}
|
onUpdateUserRoles={this.handleUpdateUserRoles}
|
||||||
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
||||||
onDeleteUser={this.handleDeleteUser}
|
|
||||||
links={links}
|
|
||||||
authConfig={authConfig}
|
|
||||||
actionsConfig={actionsConfig}
|
|
||||||
notify={notify}
|
|
||||||
isLoading={this.state.isLoading}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {arrayOf, bool, func, shape, string} = PropTypes
|
|
||||||
|
|
||||||
AllUsersPage.propTypes = {
|
|
||||||
links: shape({
|
|
||||||
users: string.isRequired,
|
|
||||||
config: shape({
|
|
||||||
auth: string.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
}),
|
|
||||||
meID: string.isRequired,
|
|
||||||
users: arrayOf(shape),
|
|
||||||
organizations: arrayOf(shape),
|
|
||||||
actionsAdmin: shape({
|
|
||||||
loadUsersAsync: func.isRequired,
|
|
||||||
loadOrganizationsAsync: func.isRequired,
|
|
||||||
createUserAsync: func.isRequired,
|
|
||||||
updateUserAsync: func.isRequired,
|
|
||||||
deleteUserAsync: func.isRequired,
|
|
||||||
}),
|
|
||||||
actionsConfig: shape({
|
|
||||||
getAuthConfigAsync: func.isRequired,
|
|
||||||
updateAuthConfigAsync: func.isRequired,
|
|
||||||
}),
|
|
||||||
authConfig: shape({
|
|
||||||
superAdminNewUsers: bool,
|
|
||||||
}),
|
|
||||||
notify: func.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = ({
|
const mapStateToProps = ({
|
||||||
links,
|
links,
|
||||||
adminChronograf: {organizations, users},
|
adminChronograf: {organizations, users},
|
|
@ -0,0 +1,54 @@
|
||||||
|
export interface Organization {
|
||||||
|
defaultRole: string
|
||||||
|
id: string
|
||||||
|
links: {
|
||||||
|
self: string
|
||||||
|
}
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Role {
|
||||||
|
name: string
|
||||||
|
organization: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: string
|
||||||
|
links: {self: string}
|
||||||
|
name: string
|
||||||
|
provider: string
|
||||||
|
roles: Role[]
|
||||||
|
scheme: string
|
||||||
|
superAdmin: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Auth {
|
||||||
|
callback: string
|
||||||
|
label: string
|
||||||
|
login: string
|
||||||
|
logout: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthConfig {
|
||||||
|
auth: string
|
||||||
|
self: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthLinks {
|
||||||
|
allUsers: string
|
||||||
|
auth: Auth[]
|
||||||
|
config: AuthConfig
|
||||||
|
dashboards: string
|
||||||
|
environment: string
|
||||||
|
external: {
|
||||||
|
statusFeed?: string
|
||||||
|
}
|
||||||
|
layouts: string
|
||||||
|
logout: string
|
||||||
|
mappings: string
|
||||||
|
me: string
|
||||||
|
organizations: string
|
||||||
|
sources: string
|
||||||
|
users: string
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import {Query} from './query'
|
import {Query} from './query'
|
||||||
import {Source, Kapacitor} from './sources'
|
import {Source, Kapacitor} from './sources'
|
||||||
|
import {AuthLinks, Role, User, Organization} from './auth'
|
||||||
|
|
||||||
export {Query, Source, Kapacitor}
|
export {Query, Source, Kapacitor, AuthLinks, User, Organization, Role}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {AllUsersPage} from 'src/admin/containers/chronograf/AllUsersPage'
|
||||||
|
import {shallow} from 'enzyme'
|
||||||
|
|
||||||
|
import {authLinks as links} from 'test/resources'
|
||||||
|
|
||||||
|
const noop = () => {}
|
||||||
|
|
||||||
|
const setup = (override = {}) => {
|
||||||
|
const props = {
|
||||||
|
links,
|
||||||
|
meID: '1',
|
||||||
|
users: [],
|
||||||
|
organizations: [],
|
||||||
|
actionsAdmin: {
|
||||||
|
loadUsersAsync: noop,
|
||||||
|
loadOrganizationsAsync: noop,
|
||||||
|
createUserAsync: noop,
|
||||||
|
updateUserAsync: noop,
|
||||||
|
deleteUserAsync: noop,
|
||||||
|
},
|
||||||
|
actionsConfig: {
|
||||||
|
getAuthConfigAsync: noop,
|
||||||
|
updateAuthConfigAsync: noop,
|
||||||
|
},
|
||||||
|
authConfig: {
|
||||||
|
superAdminNewUsers: false,
|
||||||
|
},
|
||||||
|
notify: noop,
|
||||||
|
...override,
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapper = shallow(<AllUsersPage {...props} />)
|
||||||
|
|
||||||
|
return {
|
||||||
|
wrapper,
|
||||||
|
props,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Admin.Containers.Chronograf.AllUsersPage', () => {
|
||||||
|
describe('rendering', () => {
|
||||||
|
it('renders', () => {
|
||||||
|
const {wrapper} = setup()
|
||||||
|
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,3 +1,14 @@
|
||||||
|
export const links = {
|
||||||
|
self: '/chronograf/v1/sources/16',
|
||||||
|
kapacitors: '/chronograf/v1/sources/16/kapacitors',
|
||||||
|
proxy: '/chronograf/v1/sources/16/proxy',
|
||||||
|
queries: '/chronograf/v1/sources/16/queries',
|
||||||
|
write: '/chronograf/v1/sources/16/write',
|
||||||
|
permissions: '/chronograf/v1/sources/16/permissions',
|
||||||
|
users: '/chronograf/v1/sources/16/users',
|
||||||
|
databases: '/chronograf/v1/sources/16/dbs',
|
||||||
|
}
|
||||||
|
|
||||||
export const source = {
|
export const source = {
|
||||||
id: '16',
|
id: '16',
|
||||||
name: 'ssl',
|
name: 'ssl',
|
||||||
|
@ -9,16 +20,7 @@ export const source = {
|
||||||
telegraf: 'telegraf',
|
telegraf: 'telegraf',
|
||||||
organization: '0',
|
organization: '0',
|
||||||
role: 'viewer',
|
role: 'viewer',
|
||||||
links: {
|
links,
|
||||||
self: '/chronograf/v1/sources/16',
|
|
||||||
kapacitors: '/chronograf/v1/sources/16/kapacitors',
|
|
||||||
proxy: '/chronograf/v1/sources/16/proxy',
|
|
||||||
queries: '/chronograf/v1/sources/16/queries',
|
|
||||||
write: '/chronograf/v1/sources/16/write',
|
|
||||||
permissions: '/chronograf/v1/sources/16/permissions',
|
|
||||||
users: '/chronograf/v1/sources/16/users',
|
|
||||||
databases: '/chronograf/v1/sources/16/dbs',
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const query = {
|
export const query = {
|
||||||
|
@ -60,3 +62,32 @@ export const kapacitor = {
|
||||||
proxy: '/proxy/kapacitor/1',
|
proxy: '/proxy/kapacitor/1',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const authLinks = {
|
||||||
|
allUsers: '/chronograf/v1/users',
|
||||||
|
auth: [
|
||||||
|
{
|
||||||
|
callback: '/oauth/github/callback',
|
||||||
|
label: 'Github',
|
||||||
|
login: '/oauth/github/login',
|
||||||
|
logout: '/oauth/github/logout',
|
||||||
|
name: 'github',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
auth: '/chronograf/v1/config/auth',
|
||||||
|
self: '/chronograf/v1/config',
|
||||||
|
},
|
||||||
|
dashboards: '/chronograf/v1/dashboards',
|
||||||
|
environment: '/chronograf/v1/env',
|
||||||
|
external: {
|
||||||
|
statusFeed: 'https://www.influxdata.com/feed/json',
|
||||||
|
},
|
||||||
|
layouts: '/chronograf/v1/layouts',
|
||||||
|
logout: '/oauth/logout',
|
||||||
|
mappings: '/chronograf/v1/mappings',
|
||||||
|
me: '/chronograf/v1/me',
|
||||||
|
organizations: '/chronograf/v1/organizations',
|
||||||
|
sources: '/chronograf/v1/sources',
|
||||||
|
users: '/chronograf/v1/organizations/default/users',
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue