import React, { Component, Fragment } from 'react'; import moment from 'moment'; import { Link } from '@reach/router'; 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'; import SysAdminUserStatusEditor from '../../../components/select-editor/sysadmin-user-status-editor'; import SysAdminUserRoleEditor from '../../../components/select-editor/sysadmin-user-role-editor'; import SelectEditor from '../../../components/select-editor/select-editor'; import OpMenu from '../../../components/dialog/op-menu'; import SysAdminUserSetQuotaDialog from '../../../components/dialog/sysadmin-dialog/set-quota'; import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog'; import UserLink from '../user-link'; const { availableRoles, availableAdminRoles, institutions } = window.sysadmin.pageOptions; class Content extends Component { constructor(props) { super(props); this.state = { isItemFreezed: false }; } onFreezedItem = () => { this.setState({isItemFreezed: true}); } onUnfreezedItem = () => { this.setState({isItemFreezed: false}); } getPreviousPage = () => { this.props.getListByPage(this.props.currentPage - 1); } getNextPage = () => { this.props.getListByPage(this.props.currentPage + 1); } sortByQuotaUsage = (e) => { e.preventDefault(); this.props.sortByQuotaUsage(); } render() { const { isAdmin, loading, errorMsg, items, isAllUsersSelected, curPerPage, hasNextPage, currentPage, sortBy, sortOrder } = this.props; if (loading) { return ; } else if (errorMsg) { return

{errorMsg}

; } else { const emptyTip = (

{gettext('No users')}

); let columns = []; let sortIcon; if (sortBy == '') { // initial sort icon sortIcon = ; } else { sortIcon = ; } const spaceText = gettext('Space Used'); const spaceEl = sortBy != undefined ? // only offer 'sort' for 'DB' & 'LDAPImported' users {spaceText} {sortIcon} : spaceText; const colSpaceText = {spaceEl}{` / ${gettext('Quota')}`}; const colNameText = `${gettext('Name')} / ${gettext('Contact Email')}`; const colCreatedText = `${gettext('Created At')} / ${gettext('Last Login')}`; 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 = ( {columns.map((item, index) => { return ; })} {items.map((item, index) => { return (); })}
{item.text}
{(!this.props.isAdmin && !this.props.isSearchResult) && }
); return items.length ? table : emptyTip; } } } class Item extends Component { constructor(props) { super(props); this.state = { isOpIconShown: false, highlight: false, isSetQuotaDialogOpen: false, isDeleteUserDialogOpen: false, isResetUserPasswordDialogOpen: false, isRevokeAdminDialogOpen: false }; } handleMouseEnter = () => { if (!this.props.isItemFreezed) { this.setState({ isOpIconShown: true, highlight: true }); } } handleMouseLeave = () => { if (!this.props.isItemFreezed) { this.setState({ isOpIconShown: false, highlight: false }); } } onUnfreezedItem = () => { this.setState({ highlight: false, isOpIconShow: false }); this.props.onUnfreezedItem(); } toggleSetQuotaDialog = () => { this.setState({isSetQuotaDialogOpen: !this.state.isSetQuotaDialogOpen}); } toggleDeleteUserDialog = () => { this.setState({isDeleteUserDialogOpen: !this.state.isDeleteUserDialogOpen}); } toggleResetUserPasswordDialog = () => { this.setState({isResetUserPasswordDialogOpen: !this.state.isResetUserPasswordDialogOpen}); } toggleRevokeAdminDialog = () => { this.setState({isRevokeAdminDialogOpen: !this.state.isRevokeAdminDialogOpen}); } onUserSelected = () => { this.props.onUserSelected(this.props.item); } updateStatus= (value) => { const isActive = value == 'active'; if (isActive) { toaster.notify(gettext('It may take some time, please wait.')); } this.props.updateUser(this.props.item.email, 'is_active', isActive); } updateRole = (value) => { this.props.updateUser(this.props.item.email, 'role', value); } updateAdminRole = (value) => { this.props.updateAdminRole(this.props.item.email, value); } 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; } } updateInstitution = (value) => { this.props.updateUser(this.props.item.email, 'institution', value); } translateInstitution = (inst) => { return inst; } updateQuota = (value) => { this.props.updateUser(this.props.item.email, 'quota_total', value); } deleteUser = () => { toaster.notify(gettext('It may take some time, please wait.')); this.props.deleteUser(this.props.item.email); } 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); }); } revokeAdmin = () => { const { item } = this.props; this.props.revokeAdmin(item.email, item.name); } getMenuOperations = () => { const { 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; } translateOperations = (item) => { let translateResult = ''; switch (item) { case 'Delete': translateResult = gettext('Delete'); break; case 'Reset Password': translateResult = gettext('Reset Password'); break; case 'Revoke Admin': translateResult = gettext('Revoke Admin'); break; } return translateResult; } onMenuItemClick = (operation) => { switch(operation) { case 'Delete': this.toggleDeleteUserDialog(); break; case 'Reset Password': this.toggleResetUserPasswordDialog(); break; case 'Revoke Admin': this.toggleRevokeAdminDialog(); break; default: break; } } render() { const { item, isAdmin } = this.props; const { isOpIconShown, isSetQuotaDialogOpen, isDeleteUserDialogOpen, isResetUserPasswordDialogOpen, isRevokeAdminDialogOpen } = this.state; const itemName = '' + Utils.HTMLescape(item.name) + ''; 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); return ( {item.contact_email &&
{item.contact_email}
} {item.org_id &&
({item.org_name})
} {isPro && {isAdmin ? : } } {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`} {(multiInstitution && !isAdmin) && 0} options={institutions} currentOption={item.institution} onOptionChanged={this.updateInstitution} translateOption={this.translateInstitution} /> } {`${item.create_time ? moment(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`}
{`${item.last_login ? moment(item.last_login).fromNow() : '--'}`} {(item.email != username && isOpIconShown) && } {isSetQuotaDialogOpen && } {isDeleteUserDialogOpen && } {isResetUserPasswordDialogOpen && } {isRevokeAdminDialogOpen && }
); } } export default Content;