Refactor UsersTable into sub-components

remotes/origin/multitenancy_ui_superadmin_admin_panel_and_org_switch
Alex P 2017-11-01 14:02:44 -07:00
parent 6f20e5b21d
commit bd2bbbf6ab
4 changed files with 234 additions and 157 deletions

View File

@ -2,15 +2,8 @@ import React, {Component, PropTypes} from 'react'
import _ from 'lodash' import _ from 'lodash'
import Dropdown from 'shared/components/Dropdown' import UsersTableRow from 'src/admin/components/chronograf/UsersTableRow'
import {
DUMMY_ORGS,
DEFAULT_ORG,
NO_ORG,
NO_ROLE,
USER_ROLES,
} from 'src/admin/constants/dummyUsers'
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing' import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
class ChronografUsersTable extends Component { class ChronografUsersTable extends Component {
@ -26,158 +19,20 @@ class ChronografUsersTable extends Component {
this.props.onUpdateUserRole(user, currentRole, newRole) this.props.onUpdateUserRole(user, currentRole, newRole)
} }
renderOrgCell = user => {
const {organizationName} = this.props
// Expects Users to always have at least 1 role (as a member of the default org)
if (user.roles.length === 1) {
return (
<Dropdown
items={DUMMY_ORGS.filter(org => {
return !(org.name === DEFAULT_ORG || org.name === NO_ORG)
}).map(r => ({
...r,
text: r.name,
}))}
selected={NO_ORG}
onChoose={this.handleChangeUserRole(user, NO_ROLE)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-190"
/>
)
}
if (organizationName === DEFAULT_ORG) {
return user.roles
.filter(role => {
return !(role.organizationName === DEFAULT_ORG)
})
.map((role, i) =>
<span key={i} className="chronograf-user--org">
<a
href="#"
onClick={this.handleChooseFilter(role.organizationName)}
>
{role.organizationName}
</a>
</span>
)
}
const currentOrg = user.roles.find(
role => role.organizationName === organizationName
)
return (
<span className="chronograf-user--org">
<a
href="#"
onClick={this.handleChooseFilter(currentOrg.organizationName)}
>
{currentOrg.organizationName}
</a>
</span>
)
}
renderRoleCell = user => {
const {organizationName} = this.props
// User must be part of more than one organization to be able to be assigned a role
if (user.roles.length === 1) {
return <span className="chronograf-user--role">N/A</span>
}
if (organizationName === DEFAULT_ORG) {
return user.roles
.filter(role => {
return !(role.organizationName === DEFAULT_ORG)
})
.map((role, i) =>
<Dropdown
key={i}
items={USER_ROLES.map(r => ({
...r,
text: r.name,
}))}
selected={role.name}
onChoose={this.handleChangeUserRole(user, role)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-80"
/>
)
}
const currentRole = user.roles.find(
role => role.organizationName === organizationName
)
return (
<span className="chronograf-user--role">
<Dropdown
items={USER_ROLES.map(r => ({
...r,
text: r.name,
}))}
selected={currentRole.name}
onChoose={this.handleChangeUserRole(user, currentRole)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-80"
/>
</span>
)
}
renderTableRows = filteredUsers => {
const {colOrg, colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
const {onToggleUserSelected, selectedUsers, isSameUser} = this.props
return filteredUsers.map((user, i) => {
const isSelected = selectedUsers.find(u => isSameUser(user, u))
return (
<tr key={i} className={isSelected ? 'selected' : null}>
<td
onClick={onToggleUserSelected(user)}
className="chronograf-admin-table--check-col chronograf-admin-table--selectable"
>
<div className="user-checkbox" />
</td>
<td
onClick={onToggleUserSelected(user)}
className="chronograf-admin-table--selectable"
>
<strong>
{user.name}
</strong>
</td>
<td style={{width: colOrg}}>
{this.renderOrgCell(user)}
</td>
<td style={{width: colRole}}>
{this.renderRoleCell(user)}
</td>
<td style={{width: colSuperAdmin}}>
{user.superadmin ? 'Yes' : '--'}
</td>
<td style={{width: colProvider}}>
{user.provider}
</td>
<td className="text-right" style={{width: colScheme}}>
{user.scheme}
</td>
</tr>
)
})
}
areSameUsers = (usersA, usersB) => { areSameUsers = (usersA, usersB) => {
const {isSameUser} = this.props const {isSameUser} = this.props
return !_.differenceWith(usersA, usersB, isSameUser).length return !_.differenceWith(usersA, usersB, isSameUser).length
} }
render() { render() {
const {filteredUsers, onToggleAllUsersSelected, selectedUsers} = this.props const {
organizationName,
filteredUsers,
onToggleAllUsersSelected,
onToggleUserSelected,
selectedUsers,
isSameUser,
} = this.props
const {colOrg, colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE const {colOrg, colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
const areAllSelected = this.areSameUsers(filteredUsers, selectedUsers) const areAllSelected = this.areSameUsers(filteredUsers, selectedUsers)
@ -205,7 +60,18 @@ class ChronografUsersTable extends Component {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{this.renderTableRows(filteredUsers)} {filteredUsers.map((user, i) =>
<UsersTableRow
user={user}
key={i}
onToggleUserSelected={onToggleUserSelected}
selectedUsers={selectedUsers}
isSameUser={isSameUser}
organizationName={organizationName}
onChangeUserRole={this.handleChangeUserRole}
onChooseFilter={this.handleChooseFilter}
/>
)}
</tbody> </tbody>
</table> </table>
) )
@ -215,8 +81,8 @@ class ChronografUsersTable extends Component {
const {arrayOf, func, shape, string} = PropTypes const {arrayOf, func, shape, string} = PropTypes
ChronografUsersTable.propTypes = { ChronografUsersTable.propTypes = {
filteredUsers: arrayOf(shape), filteredUsers: arrayOf(shape()),
selectedUsers: arrayOf(shape), selectedUsers: arrayOf(shape()),
onFilterUsers: func.isRequired, onFilterUsers: func.isRequired,
onToggleUserSelected: func.isRequired, onToggleUserSelected: func.isRequired,
onToggleAllUsersSelected: func.isRequired, onToggleAllUsersSelected: func.isRequired,

View File

@ -0,0 +1,72 @@
import React, {PropTypes} from 'react'
import Dropdown from 'shared/components/Dropdown'
import {
DEFAULT_ORG,
DUMMY_ORGS,
NO_ORG,
NO_ROLE,
} from 'src/admin/constants/dummyUsers'
const UsersTableOrgCell = ({
user,
organizationName,
onChangeUserRole,
onChooseFilter,
}) => {
// Expects Users to always have at least 1 role (as a member of the default org)
if (user.roles.length === 1) {
return (
<Dropdown
items={DUMMY_ORGS.filter(org => {
return !(org.name === DEFAULT_ORG || org.name === NO_ORG)
}).map(r => ({
...r,
text: r.name,
}))}
selected={NO_ORG}
onChoose={onChangeUserRole(user, NO_ROLE)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-190"
/>
)
}
if (organizationName === DEFAULT_ORG) {
return user.roles
.filter(role => {
return !(role.organizationName === DEFAULT_ORG)
})
.map((role, i) =>
<span key={i} className="chronograf-user--org">
<a href="#" onClick={onChooseFilter(role.organizationName)}>
{role.organizationName}
</a>
</span>
)
}
const currentOrg = user.roles.find(
role => role.organizationName === organizationName
)
return (
<span className="chronograf-user--org">
<a href="#" onClick={onChooseFilter(currentOrg.organizationName)}>
{currentOrg.organizationName}
</a>
</span>
)
}
const {func, shape, string} = PropTypes
UsersTableOrgCell.propTypes = {
user: shape(),
organizationName: string.isRequired,
onChangeUserRole: func.isRequired,
onChooseFilter: func.isRequired,
}
export default UsersTableOrgCell

View File

@ -0,0 +1,62 @@
import React, {PropTypes} from 'react'
import Dropdown from 'shared/components/Dropdown'
import {DEFAULT_ORG, USER_ROLES} from 'src/admin/constants/dummyUsers'
const UsersTableRoleCell = ({user, organizationName, onChangeUserRole}) => {
// User must be part of more than one organization to be able to be assigned a role
if (user.roles.length === 1) {
return <span className="chronograf-user--role">N/A</span>
}
if (organizationName === DEFAULT_ORG) {
return user.roles
.filter(role => {
return !(role.organizationName === DEFAULT_ORG)
})
.map((role, i) =>
<Dropdown
key={i}
items={USER_ROLES.map(r => ({
...r,
text: r.name,
}))}
selected={role.name}
onChoose={onChangeUserRole(user, role)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-80"
/>
)
}
const currentRole = user.roles.find(
role => role.organizationName === organizationName
)
return (
<span className="chronograf-user--role">
<Dropdown
items={USER_ROLES.map(r => ({
...r,
text: r.name,
}))}
selected={currentRole.name}
onChoose={onChangeUserRole(user, currentRole)}
buttonColor="btn-primary"
buttonSize="btn-xs"
className="dropdown-80"
/>
</span>
)
}
const {func, shape, string} = PropTypes
UsersTableRoleCell.propTypes = {
user: shape(),
organizationName: string.isRequired,
onChangeUserRole: func.isRequired,
}
export default UsersTableRoleCell

View File

@ -0,0 +1,77 @@
import React, {PropTypes} from 'react'
import UsersTableRoleCell from 'src/admin/components/chronograf/UsersTableRoleCell'
import UsersTableOrgCell from 'src/admin/components/chronograf/UsersTableOrgCell'
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
const UsersTableRow = ({
user,
organizationName,
onToggleUserSelected,
selectedUsers,
isSameUser,
onChangeUserRole,
onChooseFilter,
}) => {
const {colOrg, colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
const isSelected = selectedUsers.find(u => isSameUser(user, u))
return (
<tr className={isSelected ? 'selected' : null}>
<td
onClick={onToggleUserSelected(user)}
className="chronograf-admin-table--check-col chronograf-admin-table--selectable"
>
<div className="user-checkbox" />
</td>
<td
onClick={onToggleUserSelected(user)}
className="chronograf-admin-table--selectable"
>
<strong>
{user.name}
</strong>
</td>
<td style={{width: colOrg}}>
<UsersTableOrgCell
user={user}
organizationName={organizationName}
onChangeUserRole={onChangeUserRole}
onChooseFilter={onChooseFilter}
/>
</td>
<td style={{width: colRole}}>
<UsersTableRoleCell
user={user}
organizationName={organizationName}
onChangeUserRole={onChangeUserRole}
/>
</td>
<td style={{width: colSuperAdmin}}>
{user.superadmin ? 'Yes' : '--'}
</td>
<td style={{width: colProvider}}>
{user.provider}
</td>
<td className="text-right" style={{width: colScheme}}>
{user.scheme}
</td>
</tr>
)
}
const {arrayOf, func, shape, string} = PropTypes
UsersTableRow.propTypes = {
user: shape(),
organizationName: string.isRequired,
onToggleUserSelected: func.isRequired,
selectedUsers: arrayOf(shape()),
isSameUser: func.isRequired,
onChangeUserRole: func.isRequired,
onChooseFilter: func.isRequired,
}
export default UsersTableRow