Merge pull request #2452 from influxdata/multitenancy_ui_prevent_self_deletion
Disable 'Remove' button for self in Chronograf UsersTablepull/2469/head
commit
75e1c46577
|
@ -22,6 +22,7 @@ const AdminTabs = ({
|
||||||
onUpdateUserRole,
|
onUpdateUserRole,
|
||||||
onUpdateUserSuperAdmin,
|
onUpdateUserSuperAdmin,
|
||||||
onDeleteUser,
|
onDeleteUser,
|
||||||
|
meID,
|
||||||
}) => {
|
}) => {
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,7 @@ const AdminTabs = ({
|
||||||
onUpdateUserRole={onUpdateUserRole}
|
onUpdateUserRole={onUpdateUserRole}
|
||||||
onUpdateUserSuperAdmin={onUpdateUserSuperAdmin}
|
onUpdateUserSuperAdmin={onUpdateUserSuperAdmin}
|
||||||
onDeleteUser={onDeleteUser}
|
onDeleteUser={onDeleteUser}
|
||||||
|
meID={meID}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -65,16 +67,34 @@ const AdminTabs = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const {arrayOf, func, shape, string} = PropTypes
|
const {arrayOf, bool, func, shape, string} = PropTypes
|
||||||
|
|
||||||
AdminTabs.propTypes = {
|
AdminTabs.propTypes = {
|
||||||
meRole: string.isRequired,
|
meRole: string.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
// UsersTable
|
// UsersTable
|
||||||
users: arrayOf(shape()),
|
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({
|
organization: shape({
|
||||||
name: string.isRequired,
|
name: string.isRequired,
|
||||||
id: string.isRequired,
|
id: string.isRequired,
|
||||||
}),
|
}).isRequired,
|
||||||
onCreateUser: func.isRequired,
|
onCreateUser: func.isRequired,
|
||||||
onUpdateUserRole: func.isRequired,
|
onUpdateUserRole: func.isRequired,
|
||||||
onUpdateUserSuperAdmin: func.isRequired,
|
onUpdateUserSuperAdmin: func.isRequired,
|
||||||
|
|
|
@ -40,7 +40,7 @@ class UsersTable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {organization, users, onCreateUser} = this.props
|
const {organization, users, onCreateUser, meID} = this.props
|
||||||
|
|
||||||
const {isCreatingUser} = this.state
|
const {isCreatingUser} = this.state
|
||||||
const {
|
const {
|
||||||
|
@ -94,6 +94,7 @@ class UsersTable extends Component {
|
||||||
onChangeUserRole={this.handleChangeUserRole}
|
onChangeUserRole={this.handleChangeUserRole}
|
||||||
onChangeSuperAdmin={this.handleChangeSuperAdmin}
|
onChangeSuperAdmin={this.handleChangeSuperAdmin}
|
||||||
onDelete={this.handleDeleteUser}
|
onDelete={this.handleDeleteUser}
|
||||||
|
meID={meID}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
: <tr className="table-empty-state">
|
: <tr className="table-empty-state">
|
||||||
|
@ -130,5 +131,6 @@ UsersTable.propTypes = {
|
||||||
onUpdateUserRole: func.isRequired,
|
onUpdateUserRole: func.isRequired,
|
||||||
onUpdateUserSuperAdmin: func.isRequired,
|
onUpdateUserSuperAdmin: func.isRequired,
|
||||||
onDeleteUser: func.isRequired,
|
onDeleteUser: func.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
}
|
}
|
||||||
export default UsersTable
|
export default UsersTable
|
||||||
|
|
|
@ -15,6 +15,7 @@ const UsersTableRow = ({
|
||||||
onChangeUserRole,
|
onChangeUserRole,
|
||||||
onChangeSuperAdmin,
|
onChangeSuperAdmin,
|
||||||
onDelete,
|
onDelete,
|
||||||
|
meID,
|
||||||
}) => {
|
}) => {
|
||||||
const {colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
|
const {colRole, colSuperAdmin, colProvider, colScheme} = USERS_TABLE
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ const UsersTableRow = ({
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
item={user}
|
item={user}
|
||||||
buttonSize="btn-xs"
|
buttonSize="btn-xs"
|
||||||
|
disabled={user.id === meID}
|
||||||
/>
|
/>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
|
@ -81,6 +83,7 @@ UsersTableRow.propTypes = {
|
||||||
onChangeUserRole: func.isRequired,
|
onChangeUserRole: func.isRequired,
|
||||||
onChangeSuperAdmin: func.isRequired,
|
onChangeSuperAdmin: func.isRequired,
|
||||||
onDelete: func.isRequired,
|
onDelete: func.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UsersTableRow
|
export default UsersTableRow
|
||||||
|
|
|
@ -11,10 +11,10 @@ import FancyScrollbar from 'shared/components/FancyScrollbar'
|
||||||
class AdminChronografPage extends Component {
|
class AdminChronografPage extends Component {
|
||||||
// TODO: revisit this, possibly don't call setState if both are deep equal
|
// TODO: revisit this, possibly don't call setState if both are deep equal
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const {currentOrganization} = nextProps
|
const {meCurrentOrganization} = nextProps
|
||||||
|
|
||||||
const hasChangedCurrentOrganization =
|
const hasChangedCurrentOrganization =
|
||||||
currentOrganization.id !== this.props.currentOrganization.id
|
meCurrentOrganization.id !== this.props.meCurrentOrganization.id
|
||||||
|
|
||||||
if (hasChangedCurrentOrganization) {
|
if (hasChangedCurrentOrganization) {
|
||||||
this.loadUsers()
|
this.loadUsers()
|
||||||
|
@ -64,7 +64,7 @@ class AdminChronografPage extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {users, currentOrganization, meRole} = this.props
|
const {users, meCurrentOrganization, meRole, meID} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="page">
|
<div className="page">
|
||||||
|
@ -81,9 +81,10 @@ class AdminChronografPage extends Component {
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<AdminTabs
|
<AdminTabs
|
||||||
meRole={meRole}
|
meRole={meRole}
|
||||||
|
meID={meID}
|
||||||
// UsersTable
|
// UsersTable
|
||||||
users={users}
|
users={users}
|
||||||
organization={currentOrganization}
|
organization={meCurrentOrganization}
|
||||||
onCreateUser={this.handleCreateUser}
|
onCreateUser={this.handleCreateUser}
|
||||||
onUpdateUserRole={this.handleUpdateUserRole}
|
onUpdateUserRole={this.handleUpdateUserRole}
|
||||||
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
onUpdateUserSuperAdmin={this.handleUpdateUserSuperAdmin}
|
||||||
|
@ -105,11 +106,12 @@ AdminChronografPage.propTypes = {
|
||||||
users: string.isRequired,
|
users: string.isRequired,
|
||||||
}),
|
}),
|
||||||
users: arrayOf(shape),
|
users: arrayOf(shape),
|
||||||
currentOrganization: shape({
|
meCurrentOrganization: shape({
|
||||||
id: string.isRequired,
|
id: string.isRequired,
|
||||||
name: string.isRequired,
|
name: string.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
meRole: string.isRequired,
|
meRole: string.isRequired,
|
||||||
|
meID: string.isRequired,
|
||||||
actions: shape({
|
actions: shape({
|
||||||
loadUsersAsync: func.isRequired,
|
loadUsersAsync: func.isRequired,
|
||||||
createUserAsync: func.isRequired,
|
createUserAsync: func.isRequired,
|
||||||
|
@ -122,12 +124,15 @@ AdminChronografPage.propTypes = {
|
||||||
const mapStateToProps = ({
|
const mapStateToProps = ({
|
||||||
links,
|
links,
|
||||||
adminChronograf: {users},
|
adminChronograf: {users},
|
||||||
auth: {me: {currentOrganization, role: meRole}},
|
auth: {
|
||||||
|
me: {currentOrganization: meCurrentOrganization, role: meRole, id: meID},
|
||||||
|
},
|
||||||
}) => ({
|
}) => ({
|
||||||
links,
|
links,
|
||||||
users,
|
users,
|
||||||
currentOrganization,
|
meCurrentOrganization,
|
||||||
meRole,
|
meRole,
|
||||||
|
meID,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
|
|
@ -4,10 +4,11 @@ import classnames from 'classnames'
|
||||||
import OnClickOutside from 'shared/components/OnClickOutside'
|
import OnClickOutside from 'shared/components/OnClickOutside'
|
||||||
import ConfirmButtons from 'shared/components/ConfirmButtons'
|
import ConfirmButtons from 'shared/components/ConfirmButtons'
|
||||||
|
|
||||||
const DeleteButton = ({onClickDelete, buttonSize, text}) =>
|
const DeleteButton = ({onClickDelete, buttonSize, text, disabled}) =>
|
||||||
<button
|
<button
|
||||||
className={classnames('btn btn-danger table--show-on-row-hover', {
|
className={classnames('btn btn-danger table--show-on-row-hover', {
|
||||||
[buttonSize]: buttonSize,
|
[buttonSize]: buttonSize,
|
||||||
|
disabled,
|
||||||
})}
|
})}
|
||||||
onClick={onClickDelete}
|
onClick={onClickDelete}
|
||||||
>
|
>
|
||||||
|
@ -37,7 +38,7 @@ class DeleteConfirmButtons extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {onDelete, item, buttonSize, text} = this.props
|
const {onDelete, item, buttonSize, text, disabled} = this.props
|
||||||
const {isConfirming} = this.state
|
const {isConfirming} = this.state
|
||||||
|
|
||||||
return isConfirming
|
return isConfirming
|
||||||
|
@ -49,18 +50,20 @@ class DeleteConfirmButtons extends Component {
|
||||||
/>
|
/>
|
||||||
: <DeleteButton
|
: <DeleteButton
|
||||||
text={text}
|
text={text}
|
||||||
onClickDelete={this.handleClickDelete}
|
onClickDelete={disabled ? () => {} : this.handleClickDelete}
|
||||||
buttonSize={buttonSize}
|
buttonSize={buttonSize}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {func, oneOfType, shape, string} = PropTypes
|
const {bool, func, oneOfType, shape, string} = PropTypes
|
||||||
|
|
||||||
DeleteButton.propTypes = {
|
DeleteButton.propTypes = {
|
||||||
text: string.isRequired,
|
text: string.isRequired,
|
||||||
onClickDelete: func.isRequired,
|
onClickDelete: func.isRequired,
|
||||||
buttonSize: string,
|
buttonSize: string,
|
||||||
|
disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteButton.defaultProps = {
|
DeleteButton.defaultProps = {
|
||||||
|
@ -72,6 +75,7 @@ DeleteConfirmButtons.propTypes = {
|
||||||
item: oneOfType([(string, shape())]),
|
item: oneOfType([(string, shape())]),
|
||||||
onDelete: func.isRequired,
|
onDelete: func.isRequired,
|
||||||
buttonSize: string,
|
buttonSize: string,
|
||||||
|
disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteConfirmButtons.defaultProps = {
|
DeleteConfirmButtons.defaultProps = {
|
||||||
|
|
Loading…
Reference in New Issue