Duplicate UsersPage components into AllUsersPage; remove SuperAdmin
parent
a5ba7b035b
commit
97739e84be
|
@ -9,6 +9,7 @@ import {
|
||||||
import {Tab, Tabs, TabPanel, TabPanels, TabList} from 'shared/components/Tabs'
|
import {Tab, Tabs, TabPanel, TabPanels, TabList} from 'shared/components/Tabs'
|
||||||
import OrganizationsPage from 'src/admin/containers/chronograf/OrganizationsPage'
|
import OrganizationsPage from 'src/admin/containers/chronograf/OrganizationsPage'
|
||||||
import UsersPage from 'src/admin/containers/chronograf/UsersPage'
|
import UsersPage from 'src/admin/containers/chronograf/UsersPage'
|
||||||
|
import AllUsersPage from 'src/admin/containers/chronograf/AllUsersPage'
|
||||||
|
|
||||||
const ORGANIZATIONS_TAB_NAME = 'Organizations'
|
const ORGANIZATIONS_TAB_NAME = 'Organizations'
|
||||||
const CURRENT_ORG_USERS_TAB_NAME = 'Current Org Users'
|
const CURRENT_ORG_USERS_TAB_NAME = 'Current Org Users'
|
||||||
|
@ -36,7 +37,10 @@ const AdminTabs = ({
|
||||||
requiredRole: SUPERADMIN_ROLE,
|
requiredRole: SUPERADMIN_ROLE,
|
||||||
type: ALL_USERS_TAB_NAME,
|
type: ALL_USERS_TAB_NAME,
|
||||||
component: (
|
component: (
|
||||||
<UsersPage meID={meID} meCurrentOrganization={meCurrentOrganization} />
|
<AllUsersPage
|
||||||
|
meID={meID}
|
||||||
|
meCurrentOrganization={meCurrentOrganization}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
].filter(t => isUserAuthorized(meRole, t.requiredRole))
|
].filter(t => isUserAuthorized(meRole, t.requiredRole))
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
import React, {Component, PropTypes} from 'react'
|
||||||
|
|
||||||
|
import uuid from 'node-uuid'
|
||||||
|
|
||||||
|
import AllUsersTableHeader from 'src/admin/components/chronograf/AllUsersTableHeader'
|
||||||
|
import AllUsersTableRowNew from 'src/admin/components/chronograf/AllUsersTableRowNew'
|
||||||
|
import AllUsersTableRow from 'src/admin/components/chronograf/AllUsersTableRow'
|
||||||
|
|
||||||
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
|
||||||
|
class AllUsersTable extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isCreatingUser: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChangeUserRole = (user, currentRole) => newRole => {
|
||||||
|
this.props.onUpdateUserRole(user, currentRole, newRole)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChangeSuperAdmin = user => newStatus => {
|
||||||
|
this.props.onUpdateUserSuperAdmin(user, newStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDeleteUser = user => {
|
||||||
|
this.props.onDeleteUser(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickCreateUser = () => {
|
||||||
|
this.setState({isCreatingUser: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlurCreateUserRow = () => {
|
||||||
|
this.setState({isCreatingUser: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {organization, users, onCreateUser, meID, notify} = this.props
|
||||||
|
|
||||||
|
const {isCreatingUser} = this.state
|
||||||
|
const {
|
||||||
|
colRole,
|
||||||
|
colSuperAdmin,
|
||||||
|
colProvider,
|
||||||
|
colScheme,
|
||||||
|
colActions,
|
||||||
|
} = USERS_TABLE
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="panel panel-default">
|
||||||
|
<AllUsersTableHeader
|
||||||
|
numUsers={users.length}
|
||||||
|
onClickCreateUser={this.handleClickCreateUser}
|
||||||
|
isCreatingUser={isCreatingUser}
|
||||||
|
organization={organization}
|
||||||
|
/>
|
||||||
|
<div className="panel-body">
|
||||||
|
<table className="table table-highlight v-center chronograf-admin-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<th style={{width: colRole}} className="align-with-col-text">
|
||||||
|
Role
|
||||||
|
</th>
|
||||||
|
<th style={{width: colSuperAdmin}} className="text-center">
|
||||||
|
SuperAdmin
|
||||||
|
</th>
|
||||||
|
<th style={{width: colProvider}}>Provider</th>
|
||||||
|
<th style={{width: colScheme}}>Scheme</th>
|
||||||
|
<th className="text-right" style={{width: colActions}} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{isCreatingUser
|
||||||
|
? <AllUsersTableRowNew
|
||||||
|
organization={organization}
|
||||||
|
onBlur={this.handleBlurCreateUserRow}
|
||||||
|
onCreateUser={onCreateUser}
|
||||||
|
notify={notify}
|
||||||
|
/>
|
||||||
|
: null}
|
||||||
|
{users.length || !isCreatingUser
|
||||||
|
? users.map(user =>
|
||||||
|
<AllUsersTableRow
|
||||||
|
user={user}
|
||||||
|
key={uuid.v4()}
|
||||||
|
organization={organization}
|
||||||
|
onChangeUserRole={this.handleChangeUserRole}
|
||||||
|
onChangeSuperAdmin={this.handleChangeSuperAdmin}
|
||||||
|
onDelete={this.handleDeleteUser}
|
||||||
|
meID={meID}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
: <tr className="table-empty-state">
|
||||||
|
<th colSpan="6">
|
||||||
|
<p>No Users to display</p>
|
||||||
|
</th>
|
||||||
|
</tr>}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const {arrayOf, bool, func, shape, string} = PropTypes
|
||||||
|
|
||||||
|
AllUsersTable.propTypes = {
|
||||||
|
users: arrayOf(
|
||||||
|
shape({
|
||||||
|
id: string,
|
||||||
|
links: shape({
|
||||||
|
self: string.isRequired,
|
||||||
|
}),
|
||||||
|
name: string.isRequired,
|
||||||
|
provider: string.isRequired,
|
||||||
|
roles: arrayOf(
|
||||||
|
shape({
|
||||||
|
name: string.isRequired,
|
||||||
|
organization: string.isRequired,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
scheme: string.isRequired,
|
||||||
|
superAdmin: bool,
|
||||||
|
})
|
||||||
|
).isRequired,
|
||||||
|
organization: shape({
|
||||||
|
name: string.isRequired,
|
||||||
|
id: string.isRequired,
|
||||||
|
}),
|
||||||
|
onCreateUser: func.isRequired,
|
||||||
|
onUpdateUserRole: func.isRequired,
|
||||||
|
onUpdateUserSuperAdmin: func.isRequired,
|
||||||
|
onDeleteUser: func.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
|
notify: func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AllUsersTable
|
|
@ -0,0 +1,46 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
||||||
|
|
||||||
|
import Authorized, {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
||||||
|
|
||||||
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
|
||||||
|
const EmptyUsersTable = () => {
|
||||||
|
const {
|
||||||
|
colRole,
|
||||||
|
colSuperAdmin,
|
||||||
|
colProvider,
|
||||||
|
colScheme,
|
||||||
|
colActions,
|
||||||
|
} = USERS_TABLE
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="panel panel-default">
|
||||||
|
<UsersTableHeader />
|
||||||
|
<div className="panel-body">
|
||||||
|
<table className="table table-highlight v-center chronograf-admin-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<th style={{width: colRole}} className="align-with-col-text">
|
||||||
|
Role
|
||||||
|
</th>
|
||||||
|
<Authorized requiredRole={SUPERADMIN_ROLE}>
|
||||||
|
<th style={{width: colSuperAdmin}} className="text-center">
|
||||||
|
SuperAdmin
|
||||||
|
</th>
|
||||||
|
</Authorized>
|
||||||
|
<th style={{width: colProvider}}>Provider</th>
|
||||||
|
<th style={{width: colScheme}}>Scheme</th>
|
||||||
|
<th className="text-right" style={{width: colActions}} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody />
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EmptyUsersTable
|
|
@ -0,0 +1,55 @@
|
||||||
|
import React, {Component, PropTypes} from 'react'
|
||||||
|
|
||||||
|
class AllUsersTableHeader extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
onClickCreateUser,
|
||||||
|
numUsers,
|
||||||
|
isCreatingUser,
|
||||||
|
organization,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const panelTitle = numUsers === 1 ? `${numUsers} User` : `${numUsers} Users`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="panel-heading u-flex u-ai-center u-jc-space-between">
|
||||||
|
<h2 className="panel-title">
|
||||||
|
{panelTitle} in <em>{organization.name}</em>
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
className="btn btn-primary btn-sm"
|
||||||
|
onClick={onClickCreateUser}
|
||||||
|
disabled={isCreatingUser || !onClickCreateUser}
|
||||||
|
>
|
||||||
|
<span className="icon plus" />
|
||||||
|
Create User
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const {bool, func, shape, string, number} = PropTypes
|
||||||
|
|
||||||
|
AllUsersTableHeader.defaultProps = {
|
||||||
|
numUsers: 0,
|
||||||
|
organization: {
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
isCreatingUser: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
AllUsersTableHeader.propTypes = {
|
||||||
|
numUsers: number.isRequired,
|
||||||
|
onClickCreateUser: func,
|
||||||
|
isCreatingUser: bool.isRequired,
|
||||||
|
organization: shape({
|
||||||
|
name: string.isRequired,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AllUsersTableHeader
|
|
@ -0,0 +1,93 @@
|
||||||
|
import React, {PropTypes} from 'react'
|
||||||
|
|
||||||
|
import Dropdown from 'shared/components/Dropdown'
|
||||||
|
import SlideToggle from 'shared/components/SlideToggle'
|
||||||
|
import DeleteConfirmTableCell from 'shared/components/DeleteConfirmTableCell'
|
||||||
|
|
||||||
|
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
|
||||||
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
|
||||||
|
const AllUsersTableRow = ({
|
||||||
|
user,
|
||||||
|
organization,
|
||||||
|
onChangeUserRole,
|
||||||
|
onChangeSuperAdmin,
|
||||||
|
onDelete,
|
||||||
|
meID,
|
||||||
|
}) => {
|
||||||
|
const {colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
|
||||||
|
|
||||||
|
const dropdownRolesItems = USER_ROLES.map(r => ({
|
||||||
|
...r,
|
||||||
|
text: r.name,
|
||||||
|
}))
|
||||||
|
const currentRole = user.roles.find(
|
||||||
|
role => role.organization === organization.id
|
||||||
|
)
|
||||||
|
|
||||||
|
const userIsMe = user.id === meID
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={'chronograf-admin-table--user'}>
|
||||||
|
<td>
|
||||||
|
{userIsMe
|
||||||
|
? <strong className="chronograf-user--me">
|
||||||
|
<span className="icon user" />
|
||||||
|
{user.name}
|
||||||
|
</strong>
|
||||||
|
: <strong>
|
||||||
|
{user.name}
|
||||||
|
</strong>}
|
||||||
|
</td>
|
||||||
|
<td style={{width: colRole}}>
|
||||||
|
<span className="chronograf-user--role">
|
||||||
|
<Dropdown
|
||||||
|
items={dropdownRolesItems}
|
||||||
|
selected={currentRole.name}
|
||||||
|
onChoose={onChangeUserRole(user, currentRole)}
|
||||||
|
buttonColor="btn-primary"
|
||||||
|
buttonSize="btn-xs"
|
||||||
|
className="dropdown-stretch"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style={{width: colSuperAdmin}} className="text-center">
|
||||||
|
<SlideToggle
|
||||||
|
active={user.superAdmin}
|
||||||
|
onToggle={onChangeSuperAdmin(user)}
|
||||||
|
size="xs"
|
||||||
|
disabled={userIsMe}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td style={{width: colProvider}}>
|
||||||
|
{user.provider}
|
||||||
|
</td>
|
||||||
|
<td style={{width: colScheme}}>
|
||||||
|
{user.scheme}
|
||||||
|
</td>
|
||||||
|
<DeleteConfirmTableCell
|
||||||
|
text="Remove"
|
||||||
|
onDelete={onDelete}
|
||||||
|
item={user}
|
||||||
|
buttonSize="btn-xs"
|
||||||
|
disabled={userIsMe}
|
||||||
|
/>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const {func, shape, string} = PropTypes
|
||||||
|
|
||||||
|
AllUsersTableRow.propTypes = {
|
||||||
|
user: shape(),
|
||||||
|
organization: shape({
|
||||||
|
name: string.isRequired,
|
||||||
|
id: string.isRequired,
|
||||||
|
}),
|
||||||
|
onChangeUserRole: func.isRequired,
|
||||||
|
onChangeSuperAdmin: func.isRequired,
|
||||||
|
onDelete: func.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AllUsersTableRow
|
|
@ -0,0 +1,160 @@
|
||||||
|
import React, {Component, PropTypes} from 'react'
|
||||||
|
|
||||||
|
import Dropdown from 'shared/components/Dropdown'
|
||||||
|
|
||||||
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
|
||||||
|
|
||||||
|
class UsersTableRowNew extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
name: '',
|
||||||
|
provider: '',
|
||||||
|
scheme: 'oauth2',
|
||||||
|
role: this.props.organization.defaultRole,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInputChange = fieldName => e => {
|
||||||
|
this.setState({[fieldName]: e.target.value.trim()})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleConfirmCreateUser = () => {
|
||||||
|
const {onBlur, onCreateUser, organization} = this.props
|
||||||
|
const {name, provider, scheme, role, superAdmin} = this.state
|
||||||
|
|
||||||
|
const newUser = {
|
||||||
|
name,
|
||||||
|
provider,
|
||||||
|
scheme,
|
||||||
|
superAdmin,
|
||||||
|
roles: [
|
||||||
|
{
|
||||||
|
name: role,
|
||||||
|
organization: organization.id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
onCreateUser(newUser)
|
||||||
|
onBlur()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInputFocus = e => {
|
||||||
|
e.target.select()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSelectRole = newRole => {
|
||||||
|
this.setState({role: newRole.text})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown = e => {
|
||||||
|
const {name, provider} = this.state
|
||||||
|
const preventCreate = !name || !provider
|
||||||
|
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
this.props.onBlur()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
if (preventCreate) {
|
||||||
|
return this.props.notify(
|
||||||
|
'warning',
|
||||||
|
'User must have a name and provider'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.handleConfirmCreateUser()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
colRole,
|
||||||
|
colProvider,
|
||||||
|
colScheme,
|
||||||
|
colSuperAdmin,
|
||||||
|
colActions,
|
||||||
|
} = USERS_TABLE
|
||||||
|
const {onBlur} = this.props
|
||||||
|
const {name, provider, scheme, role} = this.state
|
||||||
|
|
||||||
|
const dropdownRolesItems = USER_ROLES.map(r => ({...r, text: r.name}))
|
||||||
|
const preventCreate = !name || !provider
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className="chronograf-admin-table--new-user">
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
className="form-control input-xs"
|
||||||
|
type="text"
|
||||||
|
placeholder="OAuth Username..."
|
||||||
|
autoFocus={true}
|
||||||
|
value={name}
|
||||||
|
onChange={this.handleInputChange('name')}
|
||||||
|
onKeyDown={this.handleKeyDown}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td style={{width: colRole}}>
|
||||||
|
<Dropdown
|
||||||
|
items={dropdownRolesItems}
|
||||||
|
selected={role}
|
||||||
|
onChoose={this.handleSelectRole}
|
||||||
|
buttonColor="btn-primary"
|
||||||
|
buttonSize="btn-xs"
|
||||||
|
className="dropdown-stretch"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td style={{width: colSuperAdmin}} className="text-center">
|
||||||
|
—
|
||||||
|
</td>
|
||||||
|
<td style={{width: colProvider}}>
|
||||||
|
<input
|
||||||
|
className="form-control input-xs"
|
||||||
|
type="text"
|
||||||
|
placeholder="OAuth Provider..."
|
||||||
|
value={provider}
|
||||||
|
onChange={this.handleInputChange('provider')}
|
||||||
|
onKeyDown={this.handleKeyDown}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td style={{width: colScheme}}>
|
||||||
|
<input
|
||||||
|
className="form-control input-xs disabled"
|
||||||
|
type="text"
|
||||||
|
disabled={true}
|
||||||
|
placeholder="OAuth Scheme..."
|
||||||
|
value={scheme}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td className="text-right" style={{width: colActions}}>
|
||||||
|
<button className="btn btn-xs btn-square btn-info" onClick={onBlur}>
|
||||||
|
<span className="icon remove" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-xs btn-square btn-success"
|
||||||
|
disabled={preventCreate}
|
||||||
|
onClick={this.handleConfirmCreateUser}
|
||||||
|
>
|
||||||
|
<span className="icon checkmark" />
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const {func, shape, string} = PropTypes
|
||||||
|
|
||||||
|
UsersTableRowNew.propTypes = {
|
||||||
|
organization: shape({
|
||||||
|
id: string.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
}),
|
||||||
|
onBlur: func.isRequired,
|
||||||
|
onCreateUser: func.isRequired,
|
||||||
|
notify: func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UsersTableRowNew
|
|
@ -2,18 +2,10 @@ import React from 'react'
|
||||||
|
|
||||||
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
||||||
|
|
||||||
import Authorized, {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
|
||||||
|
|
||||||
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
|
||||||
const EmptyUsersTable = () => {
|
const EmptyUsersTable = () => {
|
||||||
const {
|
const {colRole, colProvider, colScheme, colActions} = USERS_TABLE
|
||||||
colRole,
|
|
||||||
colSuperAdmin,
|
|
||||||
colProvider,
|
|
||||||
colScheme,
|
|
||||||
colActions,
|
|
||||||
} = USERS_TABLE
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panel panel-default">
|
<div className="panel panel-default">
|
||||||
|
@ -26,11 +18,6 @@ const EmptyUsersTable = () => {
|
||||||
<th style={{width: colRole}} className="align-with-col-text">
|
<th style={{width: colRole}} className="align-with-col-text">
|
||||||
Role
|
Role
|
||||||
</th>
|
</th>
|
||||||
<Authorized requiredRole={SUPERADMIN_ROLE}>
|
|
||||||
<th style={{width: colSuperAdmin}} className="text-center">
|
|
||||||
SuperAdmin
|
|
||||||
</th>
|
|
||||||
</Authorized>
|
|
||||||
<th style={{width: colProvider}}>Provider</th>
|
<th style={{width: colProvider}}>Provider</th>
|
||||||
<th style={{width: colScheme}}>Scheme</th>
|
<th style={{width: colScheme}}>Scheme</th>
|
||||||
<th className="text-right" style={{width: colActions}} />
|
<th className="text-right" style={{width: colActions}} />
|
||||||
|
|
|
@ -2,8 +2,6 @@ import React, {Component, PropTypes} from 'react'
|
||||||
|
|
||||||
import uuid from 'node-uuid'
|
import uuid from 'node-uuid'
|
||||||
|
|
||||||
import Authorized, {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
|
||||||
|
|
||||||
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
import UsersTableHeader from 'src/admin/components/chronograf/UsersTableHeader'
|
||||||
import UsersTableRowNew from 'src/admin/components/chronograf/UsersTableRowNew'
|
import UsersTableRowNew from 'src/admin/components/chronograf/UsersTableRowNew'
|
||||||
import UsersTableRow from 'src/admin/components/chronograf/UsersTableRow'
|
import UsersTableRow from 'src/admin/components/chronograf/UsersTableRow'
|
||||||
|
@ -23,10 +21,6 @@ class UsersTable extends Component {
|
||||||
this.props.onUpdateUserRole(user, currentRole, newRole)
|
this.props.onUpdateUserRole(user, currentRole, newRole)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeSuperAdmin = user => newStatus => {
|
|
||||||
this.props.onUpdateUserSuperAdmin(user, newStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteUser = user => {
|
handleDeleteUser = user => {
|
||||||
this.props.onDeleteUser(user)
|
this.props.onDeleteUser(user)
|
||||||
}
|
}
|
||||||
|
@ -43,13 +37,7 @@ class UsersTable extends Component {
|
||||||
const {organization, users, onCreateUser, meID, notify} = this.props
|
const {organization, users, onCreateUser, meID, notify} = this.props
|
||||||
|
|
||||||
const {isCreatingUser} = this.state
|
const {isCreatingUser} = this.state
|
||||||
const {
|
const {colRole, colProvider, colScheme, colActions} = USERS_TABLE
|
||||||
colRole,
|
|
||||||
colSuperAdmin,
|
|
||||||
colProvider,
|
|
||||||
colScheme,
|
|
||||||
colActions,
|
|
||||||
} = USERS_TABLE
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panel panel-default">
|
<div className="panel panel-default">
|
||||||
|
@ -67,11 +55,6 @@ class UsersTable extends Component {
|
||||||
<th style={{width: colRole}} className="align-with-col-text">
|
<th style={{width: colRole}} className="align-with-col-text">
|
||||||
Role
|
Role
|
||||||
</th>
|
</th>
|
||||||
<Authorized requiredRole={SUPERADMIN_ROLE}>
|
|
||||||
<th style={{width: colSuperAdmin}} className="text-center">
|
|
||||||
SuperAdmin
|
|
||||||
</th>
|
|
||||||
</Authorized>
|
|
||||||
<th style={{width: colProvider}}>Provider</th>
|
<th style={{width: colProvider}}>Provider</th>
|
||||||
<th style={{width: colScheme}}>Scheme</th>
|
<th style={{width: colScheme}}>Scheme</th>
|
||||||
<th className="text-right" style={{width: colActions}} />
|
<th className="text-right" style={{width: colActions}} />
|
||||||
|
@ -93,24 +76,14 @@ class UsersTable extends Component {
|
||||||
key={uuid.v4()}
|
key={uuid.v4()}
|
||||||
organization={organization}
|
organization={organization}
|
||||||
onChangeUserRole={this.handleChangeUserRole}
|
onChangeUserRole={this.handleChangeUserRole}
|
||||||
onChangeSuperAdmin={this.handleChangeSuperAdmin}
|
|
||||||
onDelete={this.handleDeleteUser}
|
onDelete={this.handleDeleteUser}
|
||||||
meID={meID}
|
meID={meID}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
: <tr className="table-empty-state">
|
: <tr className="table-empty-state">
|
||||||
<Authorized
|
|
||||||
requiredRole={SUPERADMIN_ROLE}
|
|
||||||
replaceWithIfNotAuthorized={
|
|
||||||
<th colSpan="5">
|
<th colSpan="5">
|
||||||
<p>No Users to display</p>
|
<p>No Users to display</p>
|
||||||
</th>
|
</th>
|
||||||
}
|
|
||||||
>
|
|
||||||
<th colSpan="6">
|
|
||||||
<p>No Users to display</p>
|
|
||||||
</th>
|
|
||||||
</Authorized>
|
|
||||||
</tr>}
|
</tr>}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -120,7 +93,7 @@ class UsersTable extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {arrayOf, bool, func, shape, string} = PropTypes
|
const {arrayOf, func, shape, string} = PropTypes
|
||||||
|
|
||||||
UsersTable.propTypes = {
|
UsersTable.propTypes = {
|
||||||
users: arrayOf(
|
users: arrayOf(
|
||||||
|
@ -138,7 +111,6 @@ UsersTable.propTypes = {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
scheme: string.isRequired,
|
scheme: string.isRequired,
|
||||||
superAdmin: bool,
|
|
||||||
})
|
})
|
||||||
).isRequired,
|
).isRequired,
|
||||||
organization: shape({
|
organization: shape({
|
||||||
|
@ -147,7 +119,6 @@ UsersTable.propTypes = {
|
||||||
}),
|
}),
|
||||||
onCreateUser: func.isRequired,
|
onCreateUser: func.isRequired,
|
||||||
onUpdateUserRole: func.isRequired,
|
onUpdateUserRole: func.isRequired,
|
||||||
onUpdateUserSuperAdmin: func.isRequired,
|
|
||||||
onDeleteUser: func.isRequired,
|
onDeleteUser: func.isRequired,
|
||||||
meID: string.isRequired,
|
meID: string.isRequired,
|
||||||
notify: func.isRequired,
|
notify: func.isRequired,
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import React, {PropTypes} from 'react'
|
import React, {PropTypes} from 'react'
|
||||||
|
|
||||||
import Authorized, {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
|
||||||
|
|
||||||
import Dropdown from 'shared/components/Dropdown'
|
import Dropdown from 'shared/components/Dropdown'
|
||||||
import SlideToggle from 'shared/components/SlideToggle'
|
|
||||||
import DeleteConfirmTableCell from 'shared/components/DeleteConfirmTableCell'
|
import DeleteConfirmTableCell from 'shared/components/DeleteConfirmTableCell'
|
||||||
|
|
||||||
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
|
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
|
||||||
|
@ -13,11 +10,10 @@ const UsersTableRow = ({
|
||||||
user,
|
user,
|
||||||
organization,
|
organization,
|
||||||
onChangeUserRole,
|
onChangeUserRole,
|
||||||
onChangeSuperAdmin,
|
|
||||||
onDelete,
|
onDelete,
|
||||||
meID,
|
meID,
|
||||||
}) => {
|
}) => {
|
||||||
const {colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
|
const {colRole, colProvider, colScheme} = USERS_TABLE
|
||||||
|
|
||||||
const dropdownRolesItems = USER_ROLES.map(r => ({
|
const dropdownRolesItems = USER_ROLES.map(r => ({
|
||||||
...r,
|
...r,
|
||||||
|
@ -53,16 +49,6 @@ const UsersTableRow = ({
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<Authorized requiredRole={SUPERADMIN_ROLE}>
|
|
||||||
<td style={{width: colSuperAdmin}} className="text-center">
|
|
||||||
<SlideToggle
|
|
||||||
active={user.superAdmin}
|
|
||||||
onToggle={onChangeSuperAdmin(user)}
|
|
||||||
size="xs"
|
|
||||||
disabled={userIsMe}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</Authorized>
|
|
||||||
<td style={{width: colProvider}}>
|
<td style={{width: colProvider}}>
|
||||||
{user.provider}
|
{user.provider}
|
||||||
</td>
|
</td>
|
||||||
|
@ -89,7 +75,6 @@ UsersTableRow.propTypes = {
|
||||||
id: string.isRequired,
|
id: string.isRequired,
|
||||||
}),
|
}),
|
||||||
onChangeUserRole: func.isRequired,
|
onChangeUserRole: func.isRequired,
|
||||||
onChangeSuperAdmin: func.isRequired,
|
|
||||||
onDelete: func.isRequired,
|
onDelete: func.isRequired,
|
||||||
meID: string.isRequired,
|
meID: string.isRequired,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import React, {Component, PropTypes} from 'react'
|
import React, {Component, PropTypes} from 'react'
|
||||||
|
|
||||||
import Authorized, {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
|
||||||
|
|
||||||
import Dropdown from 'shared/components/Dropdown'
|
import Dropdown from 'shared/components/Dropdown'
|
||||||
|
|
||||||
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
|
||||||
|
@ -25,13 +23,12 @@ class UsersTableRowNew extends Component {
|
||||||
|
|
||||||
handleConfirmCreateUser = () => {
|
handleConfirmCreateUser = () => {
|
||||||
const {onBlur, onCreateUser, organization} = this.props
|
const {onBlur, onCreateUser, organization} = this.props
|
||||||
const {name, provider, scheme, role, superAdmin} = this.state
|
const {name, provider, scheme, role} = this.state
|
||||||
|
|
||||||
const newUser = {
|
const newUser = {
|
||||||
name,
|
name,
|
||||||
provider,
|
provider,
|
||||||
scheme,
|
scheme,
|
||||||
superAdmin,
|
|
||||||
roles: [
|
roles: [
|
||||||
{
|
{
|
||||||
name: role,
|
name: role,
|
||||||
|
@ -72,13 +69,7 @@ class UsersTableRowNew extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {colRole, colProvider, colScheme, colActions} = USERS_TABLE
|
||||||
colRole,
|
|
||||||
colProvider,
|
|
||||||
colScheme,
|
|
||||||
colSuperAdmin,
|
|
||||||
colActions,
|
|
||||||
} = USERS_TABLE
|
|
||||||
const {onBlur} = this.props
|
const {onBlur} = this.props
|
||||||
const {name, provider, scheme, role} = this.state
|
const {name, provider, scheme, role} = this.state
|
||||||
|
|
||||||
|
@ -108,11 +99,6 @@ class UsersTableRowNew extends Component {
|
||||||
className="dropdown-stretch"
|
className="dropdown-stretch"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<Authorized requiredRole={SUPERADMIN_ROLE}>
|
|
||||||
<td style={{width: colSuperAdmin}} className="text-center">
|
|
||||||
—
|
|
||||||
</td>
|
|
||||||
</Authorized>
|
|
||||||
<td style={{width: colProvider}}>
|
<td style={{width: colProvider}}>
|
||||||
<input
|
<input
|
||||||
className="form-control input-xs"
|
className="form-control input-xs"
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
import React, {Component, PropTypes} from 'react'
|
||||||
|
import {connect} from 'react-redux'
|
||||||
|
import {bindActionCreators} from 'redux'
|
||||||
|
|
||||||
|
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
|
||||||
|
import {publishAutoDismissingNotification} from 'shared/dispatchers'
|
||||||
|
|
||||||
|
import AllUsersTableEmpty from 'src/admin/components/chronograf/AllUsersTableEmpty'
|
||||||
|
import AllUsersTable from 'src/admin/components/chronograf/AllUsersTable'
|
||||||
|
|
||||||
|
class AllUsersPage extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreateUser = user => {
|
||||||
|
const {links, actions: {createUserAsync}} = this.props
|
||||||
|
createUserAsync(links.users, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateUserRole = (user, currentRole, {name}) => {
|
||||||
|
const {actions: {updateUserAsync}} = this.props
|
||||||
|
const updatedRole = {...currentRole, name}
|
||||||
|
const newRoles = user.roles.map(
|
||||||
|
r => (r.organization === currentRole.organization ? updatedRole : r)
|
||||||
|
)
|
||||||
|
updateUserAsync(user, {...user, roles: newRoles})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateUserSuperAdmin = (user, superAdmin) => {
|
||||||
|
const {actions: {updateUserAsync}} = this.props
|
||||||
|
const updatedUser = {...user, superAdmin}
|
||||||
|
updateUserAsync(user, updatedUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDeleteUser = user => {
|
||||||
|
const {actions: {deleteUserAsync}} = this.props
|
||||||
|
deleteUserAsync(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentWillMount() {
|
||||||
|
const {
|
||||||
|
links,
|
||||||
|
actions: {loadOrganizationsAsync, loadUsersAsync},
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
this.setState({isLoading: true})
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
loadOrganizationsAsync(links.organizations),
|
||||||
|
loadUsersAsync(links.users),
|
||||||
|
])
|
||||||
|
|
||||||
|
this.setState({isLoading: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
meCurrentOrganization,
|
||||||
|
organizations,
|
||||||
|
meID,
|
||||||
|
users,
|
||||||
|
notify,
|
||||||
|
} = this.props
|
||||||
|
const {isLoading} = this.state
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <AllUsersTableEmpty />
|
||||||
|
}
|
||||||
|
|
||||||
|
const organization = organizations.find(
|
||||||
|
o => o.id === meCurrentOrganization.id
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AllUsersTable
|
||||||
|
meID={meID}
|
||||||
|
users={users}
|
||||||
|
organization={organization}
|
||||||
|
onCreateUser={this.handleCreateUser}
|
||||||
|
onUpdateUserRole={this.handleUpdateUserRole}
|
||||||
|
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
||||||
|
onDeleteUser={this.handleDeleteUser}
|
||||||
|
notify={notify}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const {arrayOf, func, shape, string} = PropTypes
|
||||||
|
|
||||||
|
AllUsersPage.propTypes = {
|
||||||
|
links: shape({
|
||||||
|
users: string.isRequired,
|
||||||
|
}),
|
||||||
|
meID: string.isRequired,
|
||||||
|
meCurrentOrganization: shape({
|
||||||
|
id: string.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
users: arrayOf(shape),
|
||||||
|
organizations: arrayOf(shape),
|
||||||
|
actions: shape({
|
||||||
|
loadUsersAsync: func.isRequired,
|
||||||
|
loadOrganizationsAsync: func.isRequired,
|
||||||
|
createUserAsync: func.isRequired,
|
||||||
|
updateUserAsync: func.isRequired,
|
||||||
|
deleteUserAsync: func.isRequired,
|
||||||
|
}),
|
||||||
|
notify: func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = ({links, adminChronograf: {organizations, users}}) => ({
|
||||||
|
links,
|
||||||
|
organizations,
|
||||||
|
users,
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
actions: bindActionCreators(adminChronografActionCreators, dispatch),
|
||||||
|
notify: bindActionCreators(publishAutoDismissingNotification, dispatch),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(AllUsersPage)
|
|
@ -31,12 +31,6 @@ class UsersPage extends Component {
|
||||||
updateUserAsync(user, {...user, roles: newRoles})
|
updateUserAsync(user, {...user, roles: newRoles})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpdateUserSuperAdmin = (user, superAdmin) => {
|
|
||||||
const {actions: {updateUserAsync}} = this.props
|
|
||||||
const updatedUser = {...user, superAdmin}
|
|
||||||
updateUserAsync(user, updatedUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteUser = user => {
|
handleDeleteUser = user => {
|
||||||
const {actions: {deleteUserAsync}} = this.props
|
const {actions: {deleteUserAsync}} = this.props
|
||||||
deleteUserAsync(user)
|
deleteUserAsync(user)
|
||||||
|
@ -83,7 +77,6 @@ class UsersPage extends Component {
|
||||||
organization={organization}
|
organization={organization}
|
||||||
onCreateUser={this.handleCreateUser}
|
onCreateUser={this.handleCreateUser}
|
||||||
onUpdateUserRole={this.handleUpdateUserRole}
|
onUpdateUserRole={this.handleUpdateUserRole}
|
||||||
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
|
||||||
onDeleteUser={this.handleDeleteUser}
|
onDeleteUser={this.handleDeleteUser}
|
||||||
notify={notify}
|
notify={notify}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue