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 PropTypes from 'prop-types'
|
||||
import React, {PureComponent} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
|
||||
import * as configActionCreators from 'shared/actions/config'
|
||||
import {notify as notifyAction} from 'shared/actions/notifications'
|
||||
import * as configActionCreators from 'src/shared/actions/config'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
|
||||
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) {
|
||||
super(props)
|
||||
|
||||
|
@ -23,32 +52,6 @@ class AllUsersPage extends Component {
|
|||
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() {
|
||||
const {
|
||||
links,
|
||||
|
@ -65,65 +68,66 @@ class AllUsersPage extends Component {
|
|||
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() {
|
||||
const {
|
||||
organizations,
|
||||
meID,
|
||||
users,
|
||||
authConfig,
|
||||
actionsConfig,
|
||||
links,
|
||||
notify,
|
||||
authConfig,
|
||||
actionsConfig,
|
||||
organizations,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<AllUsersTable
|
||||
meID={meID}
|
||||
users={users}
|
||||
links={links}
|
||||
notify={notify}
|
||||
authConfig={authConfig}
|
||||
actionsConfig={actionsConfig}
|
||||
organizations={organizations}
|
||||
isLoading={this.state.isLoading}
|
||||
onDeleteUser={this.handleDeleteUser}
|
||||
onCreateUser={this.handleCreateUser}
|
||||
onUpdateUserRoles={this.handleUpdateUserRoles}
|
||||
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 = ({
|
||||
links,
|
||||
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 {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 = {
|
||||
id: '16',
|
||||
name: 'ssl',
|
||||
|
@ -9,16 +20,7 @@ export const source = {
|
|||
telegraf: 'telegraf',
|
||||
organization: '0',
|
||||
role: 'viewer',
|
||||
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',
|
||||
},
|
||||
links,
|
||||
}
|
||||
|
||||
export const query = {
|
||||
|
@ -60,3 +62,32 @@ export const kapacitor = {
|
|||
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