Move All New Users Are SuperAdmin toggle to AllUsersTable

pull/2733/head
Jared Scheib 2018-01-11 17:18:05 -08:00
parent 068cf733f1
commit aabbeb94ab
5 changed files with 97 additions and 74 deletions

View File

@ -25,6 +25,19 @@ class AllUsersTable extends Component {
} }
} }
handleUpdateAuthConfig = fieldName => updatedValue => {
const {
actionsConfig: {updateAuthConfigAsync},
authConfig,
links,
} = this.props
const updatedAuthConfig = {
...authConfig,
[fieldName]: updatedValue,
}
updateAuthConfigAsync(links.config.auth, authConfig, updatedAuthConfig)
}
handleAddUserToOrganization = user => newOrganization => { handleAddUserToOrganization = user => newOrganization => {
console.log('handleAddUserToOrganization', user.name, newOrganization.id) console.log('handleAddUserToOrganization', user.name, newOrganization.id)
// const newOrganizationRole = newOrganization + newOrganizationDefaultRole -- need to get this fresh from server or have server determine it, which requires a change to ValidUpdate // const newOrganizationRole = newOrganization + newOrganizationDefaultRole -- need to get this fresh from server or have server determine it, which requires a change to ValidUpdate
@ -48,7 +61,14 @@ class AllUsersTable extends Component {
} }
render() { render() {
const {users, organizations, onCreateUser, meID, notify} = this.props const {
users,
organizations,
onCreateUser,
authConfig,
meID,
notify,
} = this.props
const {isCreatingUser} = this.state const {isCreatingUser} = this.state
@ -59,6 +79,8 @@ class AllUsersTable extends Component {
numOrganizations={organizations.length} numOrganizations={organizations.length}
onClickCreateUser={this.handleClickCreateUser} onClickCreateUser={this.handleClickCreateUser}
isCreatingUser={isCreatingUser} isCreatingUser={isCreatingUser}
authConfig={authConfig}
onChangeAuthConfig={this.handleUpdateAuthConfig}
/> />
<div className="panel-body"> <div className="panel-body">
<table className="table table-highlight v-center chronograf-admin-table"> <table className="table table-highlight v-center chronograf-admin-table">
@ -117,6 +139,11 @@ class AllUsersTable extends Component {
const {arrayOf, bool, func, shape, string} = PropTypes const {arrayOf, bool, func, shape, string} = PropTypes
AllUsersTable.propTypes = { AllUsersTable.propTypes = {
links: shape({
config: shape({
auth: string.isRequired,
}).isRequired,
}).isRequired,
users: arrayOf( users: arrayOf(
shape({ shape({
id: string, id: string,
@ -145,6 +172,13 @@ AllUsersTable.propTypes = {
onUpdateUserRole: func.isRequired, onUpdateUserRole: func.isRequired,
onUpdateUserSuperAdmin: func.isRequired, onUpdateUserSuperAdmin: func.isRequired,
onDeleteUser: func.isRequired, onDeleteUser: func.isRequired,
actionsConfig: shape({
getAuthConfigAsync: func.isRequired,
updateAuthConfigAsync: func.isRequired,
}),
authConfig: shape({
superAdminNewUsers: bool,
}),
meID: string.isRequired, meID: string.isRequired,
notify: func.isRequired, notify: func.isRequired,
} }

View File

@ -1,10 +1,14 @@
import React, {PropTypes} from 'react' import React, {PropTypes} from 'react'
import SlideToggle from 'shared/components/SlideToggle'
const AllUsersTableHeader = ({ const AllUsersTableHeader = ({
numUsers, numUsers,
numOrganizations, numOrganizations,
onClickCreateUser, onClickCreateUser,
isCreatingUser, isCreatingUser,
authConfig: {superAdminNewUsers},
onChangeAuthConfig,
}) => { }) => {
const numUsersString = `${numUsers} User${numUsers === 1 ? '' : 's'}` const numUsersString = `${numUsers} User${numUsers === 1 ? '' : 's'}`
const numOrganizationsString = `${numOrganizations} Org${numOrganizations === const numOrganizationsString = `${numOrganizations} Org${numOrganizations ===
@ -17,6 +21,12 @@ const AllUsersTableHeader = ({
<h2 className="panel-title"> <h2 className="panel-title">
{numUsersString} in {numOrganizationsString} {numUsersString} in {numOrganizationsString}
</h2> </h2>
<SlideToggle
size="xs"
active={superAdminNewUsers}
onToggle={onChangeAuthConfig('superAdminNewUsers')}
/>
<span>All new users are SuperAdmins</span>
<button <button
className="btn btn-primary btn-sm" className="btn btn-primary btn-sm"
onClick={onClickCreateUser} onClick={onClickCreateUser}
@ -29,7 +39,7 @@ const AllUsersTableHeader = ({
) )
} }
const {bool, func, number} = PropTypes const {bool, func, number, shape} = PropTypes
AllUsersTableHeader.defaultProps = { AllUsersTableHeader.defaultProps = {
numUsers: 0, numUsers: 0,
@ -42,6 +52,10 @@ AllUsersTableHeader.propTypes = {
numOrganizations: number.isRequired, numOrganizations: number.isRequired,
onClickCreateUser: func, onClickCreateUser: func,
isCreatingUser: bool.isRequired, isCreatingUser: bool.isRequired,
onChangeAuthConfig: func.isRequired,
authConfig: shape({
superAdminNewUsers: bool,
}),
} }
export default AllUsersTableHeader export default AllUsersTableHeader

View File

@ -5,7 +5,6 @@ import uuid from 'node-uuid'
import OrganizationsTableRow from 'src/admin/components/chronograf/OrganizationsTableRow' import OrganizationsTableRow from 'src/admin/components/chronograf/OrganizationsTableRow'
import OrganizationsTableRowNew from 'src/admin/components/chronograf/OrganizationsTableRowNew' import OrganizationsTableRowNew from 'src/admin/components/chronograf/OrganizationsTableRowNew'
import QuestionMarkTooltip from 'shared/components/QuestionMarkTooltip' import QuestionMarkTooltip from 'shared/components/QuestionMarkTooltip'
import SlideToggle from 'shared/components/SlideToggle'
import {PUBLIC_TOOLTIP} from 'src/admin/constants/index' import {PUBLIC_TOOLTIP} from 'src/admin/constants/index'
@ -40,8 +39,6 @@ class OrganizationsTable extends Component {
onChooseDefaultRole, onChooseDefaultRole,
onTogglePublic, onTogglePublic,
currentOrganization, currentOrganization,
authConfig: {superAdminNewUsers},
onChangeAuthConfig,
} = this.props } = this.props
const {isCreatingOrganization} = this.state const {isCreatingOrganization} = this.state
@ -92,33 +89,13 @@ class OrganizationsTable extends Component {
currentOrganization={currentOrganization} currentOrganization={currentOrganization}
/> />
)} )}
<table className="table v-center superadmin-config">
<thead>
<tr>
<th style={{width: 70}}>Config</th>
<th />
</tr>
</thead>
<tbody>
<tr>
<td style={{width: 70}}>
<SlideToggle
size="xs"
active={superAdminNewUsers}
onToggle={onChangeAuthConfig('superAdminNewUsers')}
/>
</td>
<td>All new users are SuperAdmins</td>
</tr>
</tbody>
</table>
</div> </div>
</div> </div>
) )
} }
} }
const {arrayOf, bool, func, shape, string} = PropTypes const {arrayOf, func, shape, string} = PropTypes
OrganizationsTable.propTypes = { OrganizationsTable.propTypes = {
organizations: arrayOf( organizations: arrayOf(
@ -136,9 +113,5 @@ OrganizationsTable.propTypes = {
onRenameOrg: func.isRequired, onRenameOrg: func.isRequired,
onTogglePublic: func.isRequired, onTogglePublic: func.isRequired,
onChooseDefaultRole: func.isRequired, onChooseDefaultRole: func.isRequired,
onChangeAuthConfig: func.isRequired,
authConfig: shape({
superAdminNewUsers: bool,
}),
} }
export default OrganizationsTable export default OrganizationsTable

View File

@ -3,6 +3,7 @@ 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 {publishAutoDismissingNotification} from 'shared/dispatchers' import {publishAutoDismissingNotification} from 'shared/dispatchers'
import AllUsersTableEmpty from 'src/admin/components/chronograf/AllUsersTableEmpty' import AllUsersTableEmpty from 'src/admin/components/chronograf/AllUsersTableEmpty'
@ -17,13 +18,18 @@ class AllUsersPage extends Component {
} }
} }
componentDidMount() {
const {links, actionsConfig: {getAuthConfigAsync}} = this.props
getAuthConfigAsync(links.config.auth)
}
handleCreateUser = user => { handleCreateUser = user => {
const {links, actions: {createUserAsync}} = this.props const {links, actionsAdmin: {createUserAsync}} = this.props
createUserAsync(links.users, user) createUserAsync(links.users, user)
} }
handleUpdateUserRole = (user, currentRole, {name}) => { handleUpdateUserRole = (user, currentRole, {name}) => {
const {actions: {updateUserAsync}} = this.props const {actionsAdmin: {updateUserAsync}} = this.props
const updatedRole = {...currentRole, name} const updatedRole = {...currentRole, name}
const newRoles = user.roles.map( const newRoles = user.roles.map(
r => (r.organization === currentRole.organization ? updatedRole : r) r => (r.organization === currentRole.organization ? updatedRole : r)
@ -32,20 +38,20 @@ class AllUsersPage extends Component {
} }
handleUpdateUserSuperAdmin = (user, superAdmin) => { handleUpdateUserSuperAdmin = (user, superAdmin) => {
const {actions: {updateUserAsync}} = this.props const {actionsAdmin: {updateUserAsync}} = this.props
const updatedUser = {...user, superAdmin} const updatedUser = {...user, superAdmin}
updateUserAsync(user, updatedUser) updateUserAsync(user, updatedUser)
} }
handleDeleteUser = user => { handleDeleteUser = user => {
const {actions: {deleteUserAsync}} = this.props const {actionsAdmin: {deleteUserAsync}} = this.props
deleteUserAsync(user) deleteUserAsync(user)
} }
async componentWillMount() { async componentWillMount() {
const { const {
links, links,
actions: {loadOrganizationsAsync, loadUsersAsync}, actionsAdmin: {loadOrganizationsAsync, loadUsersAsync},
} = this.props } = this.props
this.setState({isLoading: true}) this.setState({isLoading: true})
@ -59,7 +65,15 @@ class AllUsersPage extends Component {
} }
render() { render() {
const {organizations, meID, users, notify} = this.props const {
organizations,
meID,
users,
authConfig,
actionsConfig,
links,
notify,
} = this.props
const {isLoading} = this.state const {isLoading} = this.state
if (isLoading) { if (isLoading) {
@ -75,39 +89,58 @@ class AllUsersPage extends Component {
onUpdateUserRole={this.handleUpdateUserRole} onUpdateUserRole={this.handleUpdateUserRole}
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin} onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
onDeleteUser={this.handleDeleteUser} onDeleteUser={this.handleDeleteUser}
links={links}
authConfig={authConfig}
actionsConfig={actionsConfig}
notify={notify} notify={notify}
/> />
) )
} }
} }
const {arrayOf, func, shape, string} = PropTypes const {arrayOf, bool, func, shape, string} = PropTypes
AllUsersPage.propTypes = { AllUsersPage.propTypes = {
links: shape({ links: shape({
users: string.isRequired, users: string.isRequired,
config: shape({
auth: string.isRequired,
}).isRequired,
}), }),
meID: string.isRequired, meID: string.isRequired,
users: arrayOf(shape), users: arrayOf(shape),
organizations: arrayOf(shape), organizations: arrayOf(shape),
actions: shape({ actionsAdmin: shape({
loadUsersAsync: func.isRequired, loadUsersAsync: func.isRequired,
loadOrganizationsAsync: func.isRequired, loadOrganizationsAsync: func.isRequired,
createUserAsync: func.isRequired, createUserAsync: func.isRequired,
updateUserAsync: func.isRequired, updateUserAsync: func.isRequired,
deleteUserAsync: func.isRequired, deleteUserAsync: func.isRequired,
}), }),
actionsConfig: shape({
getAuthConfigAsync: func.isRequired,
updateAuthConfigAsync: func.isRequired,
}),
authConfig: shape({
superAdminNewUsers: bool,
}),
notify: func.isRequired, notify: func.isRequired,
} }
const mapStateToProps = ({links, adminChronograf: {organizations, users}}) => ({ const mapStateToProps = ({
links,
adminChronograf: {organizations, users},
config: {auth: authConfig},
}) => ({
links, links,
organizations, organizations,
users, users,
authConfig,
}) })
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(adminChronografActionCreators, dispatch), actionsAdmin: bindActionCreators(adminChronografActionCreators, dispatch),
actionsConfig: bindActionCreators(configActionCreators, dispatch),
notify: bindActionCreators(publishAutoDismissingNotification, dispatch), notify: bindActionCreators(publishAutoDismissingNotification, dispatch),
}) })

View File

@ -3,20 +3,14 @@ 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 {getMeAsync} from 'shared/actions/auth' import {getMeAsync} from 'shared/actions/auth'
import OrganizationsTable from 'src/admin/components/chronograf/OrganizationsTable' import OrganizationsTable from 'src/admin/components/chronograf/OrganizationsTable'
class OrganizationsPage extends Component { class OrganizationsPage extends Component {
componentDidMount() { componentDidMount() {
const { const {links, actionsAdmin: {loadOrganizationsAsync}} = this.props
links,
actionsAdmin: {loadOrganizationsAsync},
actionsConfig: {getAuthConfigAsync},
} = this.props
loadOrganizationsAsync(links.organizations) loadOrganizationsAsync(links.organizations)
getAuthConfigAsync(links.config.auth)
} }
handleCreateOrganization = async organization => { handleCreateOrganization = async organization => {
@ -57,21 +51,8 @@ class OrganizationsPage extends Component {
this.refreshMe() this.refreshMe()
} }
handleUpdateAuthConfig = fieldName => updatedValue => {
const {
actionsConfig: {updateAuthConfigAsync},
authConfig,
links,
} = this.props
const updatedAuthConfig = {
...authConfig,
[fieldName]: updatedValue,
}
updateAuthConfigAsync(links.config.auth, authConfig, updatedAuthConfig)
}
render() { render() {
const {meCurrentOrganization, organizations, authConfig, me} = this.props const {meCurrentOrganization, organizations, me} = this.props
const organization = organizations.find( const organization = organizations.find(
o => o.id === meCurrentOrganization.id o => o.id === meCurrentOrganization.id
@ -86,15 +67,13 @@ class OrganizationsPage extends Component {
onRenameOrg={this.handleRenameOrganization} onRenameOrg={this.handleRenameOrganization}
onTogglePublic={this.handleTogglePublic} onTogglePublic={this.handleTogglePublic}
onChooseDefaultRole={this.handleChooseDefaultRole} onChooseDefaultRole={this.handleChooseDefaultRole}
authConfig={authConfig}
onChangeAuthConfig={this.handleUpdateAuthConfig}
me={me} me={me}
/> />
: <div className="page-spinner" /> : <div className="page-spinner" />
} }
} }
const {arrayOf, bool, func, shape, string} = PropTypes const {arrayOf, func, shape, string} = PropTypes
OrganizationsPage.propTypes = { OrganizationsPage.propTypes = {
links: shape({ links: shape({
@ -116,18 +95,11 @@ OrganizationsPage.propTypes = {
updateOrganizationAsync: func.isRequired, updateOrganizationAsync: func.isRequired,
deleteOrganizationAsync: func.isRequired, deleteOrganizationAsync: func.isRequired,
}), }),
actionsConfig: shape({
getAuthConfigAsync: func.isRequired,
updateAuthConfigAsync: func.isRequired,
}),
getMe: func.isRequired, getMe: func.isRequired,
meCurrentOrganization: shape({ meCurrentOrganization: shape({
name: string.isRequired, name: string.isRequired,
id: string.isRequired, id: string.isRequired,
}), }),
authConfig: shape({
superAdminNewUsers: bool,
}),
me: shape({ me: shape({
organizations: arrayOf( organizations: arrayOf(
shape({ shape({
@ -142,18 +114,15 @@ OrganizationsPage.propTypes = {
const mapStateToProps = ({ const mapStateToProps = ({
links, links,
adminChronograf: {organizations}, adminChronograf: {organizations},
config: {auth: authConfig},
auth: {me}, auth: {me},
}) => ({ }) => ({
links, links,
organizations, organizations,
authConfig,
me, me,
}) })
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
actionsAdmin: bindActionCreators(adminChronografActionCreators, dispatch), actionsAdmin: bindActionCreators(adminChronografActionCreators, dispatch),
actionsConfig: bindActionCreators(configActionCreators, dispatch),
getMe: bindActionCreators(getMeAsync, dispatch), getMe: bindActionCreators(getMeAsync, dispatch),
}) })