2019-11-14 17:08:54 +08:00
import React , { Component , Fragment } from 'react' ;
2023-09-13 08:40:50 +08:00
import PropTypes from 'prop-types' ;
2019-11-14 17:08:54 +08:00
import moment from 'moment' ;
2022-12-29 12:21:47 +08:00
import { Link } from '@gatsbyjs/reach-router' ;
2019-11-14 17:08:54 +08:00
import { Utils } from '../../../utils/utils' ;
import { seafileAPI } from '../../../utils/seafile-api' ;
import { isPro , username , gettext , multiInstitution , siteRoot } from '../../../utils/constants' ;
import toaster from '../../../components/toast' ;
import EmptyTip from '../../../components/empty-tip' ;
import Loading from '../../../components/loading' ;
import Paginator from '../../../components/paginator' ;
2023-11-24 18:21:46 +08:00
import Selector from '../../../components/single-selector' ;
2019-11-18 10:30:35 +08:00
import OpMenu from '../../../components/dialog/op-menu' ;
2019-11-14 17:08:54 +08:00
import SysAdminUserSetQuotaDialog from '../../../components/dialog/sysadmin-dialog/set-quota' ;
import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog' ;
import UserLink from '../user-link' ;
2024-06-03 12:03:41 +08:00
import UsersFilterBar from './users-filter-bar' ;
2019-11-14 17:08:54 +08:00
const { availableRoles , availableAdminRoles , institutions } = window . sysadmin . pageOptions ;
class Content extends Component {
constructor ( props ) {
super ( props ) ;
this . state = {
isItemFreezed : false
} ;
}
2023-11-24 18:21:46 +08:00
toggleItemFreezed = ( isFreezed ) => {
this . setState ( { isItemFreezed : isFreezed } ) ;
} ;
2019-11-14 17:08:54 +08:00
onFreezedItem = ( ) => {
this . setState ( { isItemFreezed : true } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
onUnfreezedItem = ( ) => {
this . setState ( { isItemFreezed : false } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
getPreviousPage = ( ) => {
2024-06-03 12:03:41 +08:00
this . props . getListByPage ( this . props . currentPage - 1 , this . props . is _active , this . props . role ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
getNextPage = ( ) => {
2024-06-03 12:03:41 +08:00
this . props . getListByPage ( this . props . currentPage + 1 , this . props . is _active , this . props . role ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2020-03-09 14:01:12 +08:00
sortByQuotaUsage = ( e ) => {
e . preventDefault ( ) ;
this . props . sortByQuotaUsage ( ) ;
2023-09-13 08:40:50 +08:00
} ;
2020-03-09 14:01:12 +08:00
2019-11-14 17:08:54 +08:00
render ( ) {
2020-03-09 14:01:12 +08:00
const {
isAdmin , loading , errorMsg , items , isAllUsersSelected ,
curPerPage , hasNextPage , currentPage ,
sortBy , sortOrder
} = this . props ;
2024-06-03 12:03:41 +08:00
2019-11-14 17:08:54 +08:00
if ( loading ) {
return < Loading / > ;
} else if ( errorMsg ) {
return < p className = "error text-center mt-4" > { errorMsg } < / p > ;
} else {
const emptyTip = (
< EmptyTip >
< h2 > { gettext ( 'No users' ) } < / h 2 >
< / E m p t y T i p >
) ;
2020-03-09 14:01:12 +08:00
2019-11-14 17:08:54 +08:00
let columns = [ ] ;
2020-03-09 14:01:12 +08:00
2020-03-25 16:13:18 +08:00
let sortIcon ;
if ( sortBy == '' ) {
// initial sort icon
2024-06-28 08:39:44 +08:00
sortIcon = < span className = "sf3-font sf3-font-sort3" > < / s p a n > ;
2020-03-25 16:13:18 +08:00
} else {
2024-06-21 12:07:58 +08:00
sortIcon = < span className = { ` sf3-font ${ sortOrder == 'asc' ? 'sf3-font-down rotate-180 d-inline-block' : 'sf3-font-down' } ` } > < / s p a n > ;
2020-03-25 16:13:18 +08:00
}
2020-03-09 14:01:12 +08:00
const spaceText = gettext ( 'Space Used' ) ;
const spaceEl =
sortBy != undefined ? // only offer 'sort' for 'DB' & 'LDAPImported' users
2023-09-13 08:40:50 +08:00
< a className = "d-inline-block table-sort-op" href = "#" onClick = { this . sortByQuotaUsage } > { spaceText } { sortIcon } < / a > :
2020-11-02 13:56:35 +08:00
spaceText ;
2020-03-09 14:01:12 +08:00
const colSpaceText = < Fragment > { spaceEl } { ` / ${ gettext ( 'Quota' ) } ` } < / F r a g m e n t > ;
2019-11-14 17:08:54 +08:00
const colNameText = ` ${ gettext ( 'Name' ) } / ${ gettext ( 'Contact Email' ) } ` ;
2021-01-22 10:41:58 +08:00
const colCreatedText = ` ${ gettext ( 'Created At' ) } / ${ gettext ( 'Last Login' ) } / ${ gettext ( 'Last Access' ) } ` ;
2019-11-14 17:08:54 +08:00
if ( isPro ) {
columns . push (
{ width : '20%' , text : colNameText } ,
{ width : '15%' , text : gettext ( 'Status' ) } ,
{ width : '15%' , text : gettext ( 'Role' ) }
) ;
} else {
columns . push (
{ width : '30%' , text : colNameText } ,
{ width : '20%' , text : gettext ( 'Status' ) }
) ;
}
if ( multiInstitution && ! isAdmin ) {
columns . push (
{ width : '14%' , text : colSpaceText } ,
{ width : '14%' , text : gettext ( 'Institution' ) } ,
{ width : '14%' , text : colCreatedText } ,
{ width : '5%' , text : '' }
) ;
} else {
columns . push (
{ width : '20%' , text : colSpaceText } ,
{ width : '22%' , text : colCreatedText } ,
{ width : '5%' , text : '' }
) ;
}
const table = (
< Fragment >
< table >
< thead >
< tr >
< th width = "3%" className = "pl-2" >
< input type = "checkbox" className = "vam" onChange = { this . props . toggleSelectAllUsers } checked = { isAllUsersSelected } / >
< / t h >
{ columns . map ( ( item , index ) => {
return < th width = { item . width } key = { index } > { item . text } < / t h > ;
} ) }
< / t r >
< / t h e a d >
< tbody >
{ items . map ( ( item , index ) => {
2024-06-03 12:03:41 +08:00
if ( index < this . props . curPerPage ) {
return (
< Item
key = { index }
item = { item }
isItemFreezed = { this . state . isItemFreezed }
onFreezedItem = { this . onFreezedItem }
onUnfreezedItem = { this . onUnfreezedItem }
toggleItemFreezed = { this . toggleItemFreezed }
updateUser = { this . props . updateUser }
deleteUser = { this . props . deleteUser }
updateAdminRole = { this . props . updateAdminRole }
revokeAdmin = { this . props . revokeAdmin }
onUserSelected = { this . props . onUserSelected }
isAdmin = { this . props . isAdmin }
isLDAPImported = { this . props . isLDAPImported }
/ >
) ;
}
return null ;
2019-11-14 17:08:54 +08:00
} ) }
< / t b o d y >
< / t a b l e >
{ ( ! this . props . isAdmin && ! this . props . isSearchResult ) &&
< Paginator
gotoPreviousPage = { this . getPreviousPage }
gotoNextPage = { this . getNextPage }
currentPage = { currentPage }
hasNextPage = { hasNextPage }
curPerPage = { curPerPage }
resetPerPage = { this . props . resetPerPage }
/ >
}
< / F r a g m e n t >
) ;
2024-06-03 12:03:41 +08:00
return (
< div >
{ this . props . currentItem === 'database' &&
< UsersFilterBar
isActive = { this . props . is _active }
role = { this . props . role }
onStatusChange = { this . props . onStatusChange }
onRoleChange = { this . props . onRoleChange }
/ >
}
{ items . length ? table : emptyTip }
< / d i v >
) ;
2019-11-14 17:08:54 +08:00
}
}
}
2023-09-13 08:40:50 +08:00
Content . propTypes = {
loading : PropTypes . bool ,
errorMsg : PropTypes . string ,
items : PropTypes . array ,
deleteItem : PropTypes . func ,
isAdmin : PropTypes . bool ,
isLDAPImported : PropTypes . bool ,
isSearchResult : PropTypes . bool ,
sortBy : PropTypes . string ,
sortByQuotaUsage : PropTypes . func ,
getListByPage : PropTypes . func ,
currentPage : PropTypes . number ,
toggleSelectAllUsers : PropTypes . func ,
isAllUsersSelected : PropTypes . bool ,
resetPerPage : PropTypes . func ,
updateUser : PropTypes . func ,
deleteUser : PropTypes . func ,
updateAdminRole : PropTypes . func ,
revokeAdmin : PropTypes . func ,
onUserSelected : PropTypes . func ,
curPerPage : PropTypes . number ,
hasNextPage : PropTypes . bool ,
sortOrder : PropTypes . string ,
2024-06-03 12:03:41 +08:00
is _active : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . number ] ) ,
role : PropTypes . string ,
currentItem : PropTypes . string ,
onStatusChange : PropTypes . func ,
onRoleChange : PropTypes . func
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
class Item extends Component {
constructor ( props ) {
super ( props ) ;
this . state = {
isOpIconShown : false ,
highlight : false ,
isSetQuotaDialogOpen : false ,
isDeleteUserDialogOpen : false ,
isResetUserPasswordDialogOpen : false ,
2024-04-23 16:26:31 +08:00
isRevokeAdminDialogOpen : false ,
isConfirmInactiveDialogOpen : false
2019-11-14 17:08:54 +08:00
} ;
}
handleMouseEnter = ( ) => {
if ( ! this . props . isItemFreezed ) {
this . setState ( {
isOpIconShown : true ,
highlight : true
} ) ;
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
handleMouseLeave = ( ) => {
if ( ! this . props . isItemFreezed ) {
this . setState ( {
isOpIconShown : false ,
highlight : false
} ) ;
2020-11-02 13:56:35 +08:00
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
onUnfreezedItem = ( ) => {
this . setState ( {
highlight : false ,
isOpIconShow : false
} ) ;
this . props . onUnfreezedItem ( ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
toggleSetQuotaDialog = ( ) => {
this . setState ( { isSetQuotaDialogOpen : ! this . state . isSetQuotaDialogOpen } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
toggleDeleteUserDialog = ( ) => {
this . setState ( { isDeleteUserDialogOpen : ! this . state . isDeleteUserDialogOpen } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
toggleResetUserPasswordDialog = ( ) => {
this . setState ( { isResetUserPasswordDialogOpen : ! this . state . isResetUserPasswordDialogOpen } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
toggleRevokeAdminDialog = ( ) => {
this . setState ( { isRevokeAdminDialogOpen : ! this . state . isRevokeAdminDialogOpen } ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2024-04-23 16:26:31 +08:00
toggleConfirmInactiveDialog = ( ) => {
this . setState ( { isConfirmInactiveDialogOpen : ! this . state . isConfirmInactiveDialogOpen } ) ;
} ;
2019-11-14 17:08:54 +08:00
onUserSelected = ( ) => {
this . props . onUserSelected ( this . props . item ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2023-11-24 18:21:46 +08:00
updateStatus = ( roleOption ) => {
const isActive = roleOption . value == 'active' ;
2019-11-14 17:08:54 +08:00
if ( isActive ) {
toaster . notify ( gettext ( 'It may take some time, please wait.' ) ) ;
}
this . props . updateUser ( this . props . item . email , 'is_active' , isActive ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2024-04-23 16:26:31 +08:00
setUserInactive = ( ) => {
this . props . updateUser ( this . props . item . email , 'is_active' , false ) ;
} ;
2023-11-24 18:21:46 +08:00
updateRole = ( roleOption ) => {
this . props . updateUser ( this . props . item . email , 'role' , roleOption . value ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2023-11-24 18:21:46 +08:00
updateAdminRole = ( roleOption ) => {
this . props . updateAdminRole ( this . props . item . email , roleOption . value ) ;
} ;
translateRole = ( role ) => {
switch ( role ) {
case 'default' :
return gettext ( 'Default' ) ;
case 'guest' :
return gettext ( 'Guest' ) ;
default :
return role ;
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
translateAdminRole = ( role ) => {
switch ( role ) {
case 'default_admin' :
return gettext ( 'Default Admin' ) ;
case 'system_admin' :
return gettext ( 'System Admin' ) ;
case 'daily_admin' :
return gettext ( 'Daily Admin' ) ;
case 'audit_admin' :
return gettext ( 'Audit Admin' ) ;
default :
return role ;
2020-11-02 13:56:35 +08:00
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2023-11-24 18:21:46 +08:00
translateStatus = ( status ) => {
switch ( status ) {
case 'active' :
return gettext ( 'Active' ) ;
case 'inactive' :
return gettext ( 'Inactive' ) ;
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
2023-11-24 18:21:46 +08:00
updateInstitution = ( instOption ) => {
this . props . updateUser ( this . props . item . email , 'institution' , instOption . value ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
updateQuota = ( value ) => {
this . props . updateUser ( this . props . item . email , 'quota_total' , value ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
deleteUser = ( ) => {
2020-03-26 18:11:14 +08:00
toaster . notify ( gettext ( 'It may take some time, please wait.' ) ) ;
2023-09-19 14:42:15 +08:00
this . props . deleteUser ( this . props . item . email , this . props . item . name ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
resetPassword = ( ) => {
toaster . notify ( gettext ( 'It may take some time, please wait.' ) ) ;
seafileAPI . sysAdminResetUserPassword ( this . props . item . email ) . then ( res => {
toaster . success ( res . data . reset _tip ) ;
} ) . catch ( ( error ) => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2020-11-02 13:56:35 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
revokeAdmin = ( ) => {
const { item } = this . props ;
this . props . revokeAdmin ( item . email , item . name ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
getMenuOperations = ( ) => {
2020-11-02 13:56:35 +08:00
const {
2019-11-14 17:08:54 +08:00
isAdmin , isLDAPImported ,
isSearchResult , item
} = this . props ;
let list = [ 'Delete' ] ;
if ( ! isLDAPImported ||
( isSearchResult && item . source == 'db' ) ) {
list . push ( 'Reset Password' ) ;
}
if ( isAdmin ) {
list = [ 'Revoke Admin' ] ;
}
return list ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
translateOperations = ( item ) => {
2020-11-02 13:56:35 +08:00
let translateResult = '' ;
2019-11-14 17:08:54 +08:00
switch ( item ) {
case 'Delete' :
translateResult = gettext ( 'Delete' ) ;
break ;
case 'Reset Password' :
translateResult = gettext ( 'Reset Password' ) ;
break ;
case 'Revoke Admin' :
translateResult = gettext ( 'Revoke Admin' ) ;
break ;
2020-11-02 13:56:35 +08:00
}
2019-11-14 17:08:54 +08:00
return translateResult ;
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
onMenuItemClick = ( operation ) => {
switch ( operation ) {
case 'Delete' :
this . toggleDeleteUserDialog ( ) ;
break ;
case 'Reset Password' :
this . toggleResetUserPasswordDialog ( ) ;
break ;
case 'Revoke Admin' :
this . toggleRevokeAdminDialog ( ) ;
break ;
default :
break ;
}
2023-09-13 08:40:50 +08:00
} ;
2019-11-14 17:08:54 +08:00
render ( ) {
const { item , isAdmin } = this . props ;
2020-11-02 13:56:35 +08:00
const {
2023-11-24 18:21:46 +08:00
highlight ,
2020-11-02 13:56:35 +08:00
isOpIconShown ,
2019-11-14 17:08:54 +08:00
isSetQuotaDialogOpen ,
isDeleteUserDialogOpen ,
isResetUserPasswordDialogOpen ,
2024-04-23 16:26:31 +08:00
isRevokeAdminDialogOpen ,
isConfirmInactiveDialogOpen
2019-11-14 17:08:54 +08:00
} = this . state ;
const itemName = '<span class="op-target">' + Utils . HTMLescape ( item . name ) + '</span>' ;
const deleteDialogMsg = gettext ( 'Are you sure you want to delete {placeholder} ?' ) . replace ( '{placeholder}' , itemName ) ;
const resetPasswordDialogMsg = gettext ( 'Are you sure you want to reset the password of {placeholder} ?' ) . replace ( '{placeholder}' , itemName ) ;
const revokeAdminDialogMsg = gettext ( 'Are you sure you want to revoke the admin permission of {placeholder} ?' ) . replace ( '{placeholder}' , itemName ) ;
2024-04-23 16:26:31 +08:00
const confirmSetUserInactiveMsg = gettext ( 'Are you sure you want to set {user_placeholder} inactive?' ) . replace ( '{user_placeholder}' , itemName ) ;
2019-11-14 17:08:54 +08:00
2023-11-24 18:21:46 +08:00
// for 'user status'
const curStatus = item . is _active ? 'active' : 'inactive' ;
this . statusOptions = [ 'active' , 'inactive' ] . map ( item => {
return {
value : item ,
text : this . translateStatus ( item ) ,
isSelected : item == curStatus
} ;
} ) ;
const currentSelectedStatusOption = this . statusOptions . filter ( item => item . isSelected ) [ 0 ] ;
let currentSelectedAdminRoleOption ;
let currentSelectedRoleOption ;
if ( isAdmin ) {
const { admin _role : curAdminRole } = item ;
this . adminRoleOptions = availableAdminRoles . map ( item => {
return {
value : item ,
text : this . translateAdminRole ( item ) ,
isSelected : item == curAdminRole
} ;
} ) ;
currentSelectedAdminRoleOption = this . adminRoleOptions . filter ( item => item . isSelected ) [ 0 ] ;
} else {
const { role : curRole } = item ;
this . roleOptions = availableRoles . map ( item => {
return {
value : item ,
text : this . translateRole ( item ) ,
isSelected : item == curRole
} ;
} ) ;
2023-12-01 11:53:51 +08:00
currentSelectedRoleOption = this . roleOptions . filter ( item => item . isSelected ) [ 0 ] || { // `|| {...}`: to be compatible with old data(roles not in the present `availableRoles`
value : curRole ,
text : this . translateRole ( curRole ) ,
isSelected : true
} ;
2023-11-24 18:21:46 +08:00
}
let currentSelectedInstOption ;
if ( multiInstitution && ! isAdmin ) {
const { institution : curInstitution } = item ;
this . instOptions = institutions . map ( item => {
return {
value : item ,
text : item ,
isSelected : item == curInstitution
} ;
} ) ;
currentSelectedInstOption = this . instOptions . filter ( item => item . isSelected ) [ 0 ] ;
}
2019-11-14 17:08:54 +08:00
return (
< Fragment >
< tr className = { this . state . highlight ? 'tr-highlight' : '' } onMouseEnter = { this . handleMouseEnter } onMouseLeave = { this . handleMouseLeave } >
< td className = "pl-2" >
< input type = "checkbox" className = "vam" onChange = { this . onUserSelected } checked = { item . isSelected } / >
< / t d >
< td >
< UserLink email = { item . email } name = { item . name } / >
2020-11-02 13:56:35 +08:00
{ item . contact _email &&
2019-11-14 17:08:54 +08:00
< Fragment >
< br / >
{ item . contact _email }
< / F r a g m e n t > }
2020-11-02 13:56:35 +08:00
{ item . org _id &&
2019-11-14 17:08:54 +08:00
< Fragment >
< br / >
< Link to = { ` ${ siteRoot } sys/organizations/ ${ item . org _id } /info/ ` } > ( { item . org _name } ) < / L i n k >
< / F r a g m e n t >
}
< / t d >
< td >
2023-11-24 18:21:46 +08:00
< Selector
isDropdownToggleShown = { highlight }
currentSelectedOption = { currentSelectedStatusOption }
options = { this . statusOptions }
selectOption = { this . updateStatus }
toggleItemFreezed = { this . props . toggleItemFreezed }
2024-04-23 16:26:31 +08:00
operationBeforeSelect = { item . is _active ? this . toggleConfirmInactiveDialog : undefined }
2019-11-14 17:08:54 +08:00
/ >
< / t d >
2020-11-02 13:56:35 +08:00
{ isPro &&
2019-11-14 17:08:54 +08:00
< td >
{ isAdmin ?
2023-11-24 18:21:46 +08:00
< Selector
isDropdownToggleShown = { highlight }
currentSelectedOption = { currentSelectedAdminRoleOption }
options = { this . adminRoleOptions }
selectOption = { this . updateAdminRole }
toggleItemFreezed = { this . props . toggleItemFreezed }
/ >
:
< Selector
isDropdownToggleShown = { highlight }
currentSelectedOption = { currentSelectedRoleOption }
options = { this . roleOptions }
selectOption = { this . updateRole }
toggleItemFreezed = { this . props . toggleItemFreezed }
2019-11-14 17:08:54 +08:00
/ >
}
< / t d >
}
< td >
{ ` ${ Utils . bytesToSize ( item . quota _usage ) } / ${ item . quota _total > 0 ? Utils . bytesToSize ( item . quota _total ) : '--' } ` }
< span
title = { gettext ( 'Edit' ) }
2024-06-28 08:39:44 +08:00
className = { ` sf3-font sf3-font-rename attr-action-icon ${ isOpIconShown ? '' : 'invisible' } ` }
2019-11-14 17:08:54 +08:00
onClick = { this . toggleSetQuotaDialog } >
< / s p a n >
< / t d >
{ ( multiInstitution && ! isAdmin ) &&
< td >
2023-11-24 18:21:46 +08:00
< Selector
isDropdownToggleShown = { highlight && institutions . length > 0 }
currentSelectedOption = { currentSelectedInstOption }
options = { this . instOptions }
selectOption = { this . updateInstitution }
toggleItemFreezed = { this . props . toggleItemFreezed }
2019-11-14 17:08:54 +08:00
/ >
< / t d >
}
< td >
{ ` ${ item . create _time ? moment ( item . create _time ) . format ( 'YYYY-MM-DD HH:mm' ) : '--' } / ` }
< br / >
{ ` ${ item . last _login ? moment ( item . last _login ) . fromNow ( ) : '--' } ` }
2021-01-22 10:41:58 +08:00
< br / >
{ ` ${ item . last _access _time ? moment ( item . last _access _time ) . fromNow ( ) : '--' } ` }
2019-11-14 17:08:54 +08:00
< / t d >
< td >
{ ( item . email != username && isOpIconShown ) &&
< OpMenu
operations = { this . getMenuOperations ( ) }
translateOperations = { this . translateOperations }
onMenuItemClick = { this . onMenuItemClick }
onFreezedItem = { this . props . onFreezedItem }
onUnfreezedItem = { this . onUnfreezedItem }
/ >
}
< / t d >
< / t r >
{ isSetQuotaDialogOpen &&
< SysAdminUserSetQuotaDialog
toggle = { this . toggleSetQuotaDialog }
updateQuota = { this . updateQuota }
/ >
}
{ isDeleteUserDialogOpen &&
< CommonOperationConfirmationDialog
title = { gettext ( 'Delete User' ) }
message = { deleteDialogMsg }
executeOperation = { this . deleteUser }
confirmBtnText = { gettext ( 'Delete' ) }
toggleDialog = { this . toggleDeleteUserDialog }
/ >
}
{ isResetUserPasswordDialogOpen &&
< CommonOperationConfirmationDialog
title = { gettext ( 'Reset Password' ) }
message = { resetPasswordDialogMsg }
executeOperation = { this . resetPassword }
confirmBtnText = { gettext ( 'Reset' ) }
toggleDialog = { this . toggleResetUserPasswordDialog }
2020-11-02 13:56:35 +08:00
/ >
2019-11-14 17:08:54 +08:00
}
{ isRevokeAdminDialogOpen &&
< CommonOperationConfirmationDialog
title = { gettext ( 'Revoke Admin' ) }
message = { revokeAdminDialogMsg }
executeOperation = { this . revokeAdmin }
confirmBtnText = { gettext ( 'Revoke' ) }
toggleDialog = { this . toggleRevokeAdminDialog }
2020-11-02 13:56:35 +08:00
/ >
2019-11-14 17:08:54 +08:00
}
2024-04-23 16:26:31 +08:00
{ isConfirmInactiveDialogOpen &&
< CommonOperationConfirmationDialog
title = { gettext ( 'Set user inactive' ) }
message = { confirmSetUserInactiveMsg }
executeOperation = { this . setUserInactive }
confirmBtnText = { gettext ( 'Set' ) }
toggleDialog = { this . toggleConfirmInactiveDialog }
/ >
}
2019-11-14 17:08:54 +08:00
< / F r a g m e n t >
) ;
}
}
2023-09-13 08:40:50 +08:00
Item . propTypes = {
item : PropTypes . object ,
isItemFreezed : PropTypes . bool ,
isAdmin : PropTypes . bool ,
isLDAPImported : PropTypes . bool ,
onFreezedItem : PropTypes . func ,
onUnfreezedItem : PropTypes . func ,
2023-11-24 18:21:46 +08:00
toggleItemFreezed : PropTypes . func . isRequired ,
2023-09-13 08:40:50 +08:00
updateUser : PropTypes . func ,
deleteUser : PropTypes . func ,
updateAdminRole : PropTypes . func ,
revokeAdmin : PropTypes . func ,
onUserSelected : PropTypes . func ,
isSearchResult : PropTypes . bool ,
} ;
2019-11-14 17:08:54 +08:00
export default Content ;