mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-10 11:21:29 +00:00
sys admin set/unset org user staff
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
import SelectEditor from './select-editor';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
isTextMode: PropTypes.bool.isRequired,
|
||||||
|
isEditIconShow: PropTypes.bool.isRequired,
|
||||||
|
statusOptions: PropTypes.array.isRequired,
|
||||||
|
currentStatus: PropTypes.string.isRequired,
|
||||||
|
onStatusChanged: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
class SysAdminUserMembershipEditor extends React.Component {
|
||||||
|
|
||||||
|
translateStatus = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'is_org_staff':
|
||||||
|
return gettext('Admin');
|
||||||
|
case 'not_is_org_staff':
|
||||||
|
return gettext('Member');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SelectEditor
|
||||||
|
isTextMode={this.props.isTextMode}
|
||||||
|
isEditIconShow={this.props.isEditIconShow}
|
||||||
|
options={this.props.statusOptions}
|
||||||
|
currentOption={this.props.currentStatus}
|
||||||
|
onOptionChanged={this.props.onStatusChanged}
|
||||||
|
translateOption={this.translateStatus}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysAdminUserMembershipEditor.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default SysAdminUserMembershipEditor;
|
@@ -8,6 +8,7 @@ import toaster from '../../../components/toast';
|
|||||||
import EmptyTip from '../../../components/empty-tip';
|
import EmptyTip from '../../../components/empty-tip';
|
||||||
import Loading from '../../../components/loading';
|
import Loading from '../../../components/loading';
|
||||||
import SysAdminUserStatusEditor from '../../../components/select-editor/sysadmin-user-status-editor';
|
import SysAdminUserStatusEditor from '../../../components/select-editor/sysadmin-user-status-editor';
|
||||||
|
import SysAdminUserMembershipEditor from '../../../components/select-editor/sysadmin-user-membership-editor';
|
||||||
import SysAdminAddUserDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-add-user-dialog';
|
import SysAdminAddUserDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-add-user-dialog';
|
||||||
import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog';
|
import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog';
|
||||||
import OpMenu from '../../../components/dialog/op-menu';
|
import OpMenu from '../../../components/dialog/op-menu';
|
||||||
@@ -50,9 +51,10 @@ class Content extends Component {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="25%">{gettext('Name')}</th>
|
<th width="25%">{gettext('Name')}</th>
|
||||||
<th width="20%">{gettext('Status')}</th>
|
<th width="15%">{gettext('Status')}</th>
|
||||||
<th width="20%">{gettext('Space Used')}</th>
|
<th width="15%">{gettext('Membership')}</th>
|
||||||
<th width="30%">{gettext('Created At')}{' / '}{gettext('Last Login')}</th>
|
<th width="15%">{gettext('Space Used')}</th>
|
||||||
|
<th width="25%">{gettext('Created At')}{' / '}{gettext('Last Login')}</th>
|
||||||
<th width="5%">{/* Operations */}</th>
|
<th width="5%">{/* Operations */}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -65,6 +67,7 @@ class Content extends Component {
|
|||||||
onFreezedItem={this.onFreezedItem}
|
onFreezedItem={this.onFreezedItem}
|
||||||
onUnfreezedItem={this.onUnfreezedItem}
|
onUnfreezedItem={this.onUnfreezedItem}
|
||||||
updateStatus={this.props.updateStatus}
|
updateStatus={this.props.updateStatus}
|
||||||
|
updateMembership={this.props.updateMembership}
|
||||||
deleteUser={this.props.deleteUser}
|
deleteUser={this.props.deleteUser}
|
||||||
/>);
|
/>);
|
||||||
})}
|
})}
|
||||||
@@ -146,6 +149,10 @@ class Item extends Component {
|
|||||||
this.props.updateStatus(this.props.item.email, statusValue);
|
this.props.updateStatus(this.props.item.email, statusValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMembership= (membershipValue) => {
|
||||||
|
this.props.updateMembership(this.props.item.email, membershipValue);
|
||||||
|
}
|
||||||
|
|
||||||
deleteUser = () => {
|
deleteUser = () => {
|
||||||
const { item } = this.props;
|
const { item } = this.props;
|
||||||
this.props.deleteUser(item.org_id, item.email);
|
this.props.deleteUser(item.org_id, item.email);
|
||||||
@@ -195,6 +202,15 @@ class Item extends Component {
|
|||||||
onStatusChanged={this.updateStatus}
|
onStatusChanged={this.updateStatus}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<SysAdminUserMembershipEditor
|
||||||
|
isTextMode={true}
|
||||||
|
isEditIconShow={isOpIconShown}
|
||||||
|
currentStatus={item.is_org_staff ? 'is_org_staff' : 'not_is_org_staff'}
|
||||||
|
statusOptions={['is_org_staff', 'not_is_org_staff']}
|
||||||
|
onStatusChanged={this.updateMembership}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
<td>{`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`}</td>
|
<td>{`${Utils.bytesToSize(item.quota_usage)} / ${item.quota_total > 0 ? Utils.bytesToSize(item.quota_total) : '--'}`}</td>
|
||||||
<td>
|
<td>
|
||||||
{moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? moment(item.last_login).fromNow() : '--'}
|
{moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')}{' / '}{item.last_login ? moment(item.last_login).fromNow() : '--'}
|
||||||
@@ -311,6 +327,22 @@ class OrgUsers extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMembership = (email, membershipValue) => {
|
||||||
|
const isOrgStaff = membershipValue == 'is_org_staff';
|
||||||
|
seafileAPI.sysAdminUpdateOrgUser(this.props.orgID, email, 'is_org_staff', isOrgStaff).then(res => {
|
||||||
|
let newUserList = this.state.userList.map(item => {
|
||||||
|
if (item.email == email) {
|
||||||
|
item.is_org_staff = res.data.is_org_staff;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
this.setState({userList: newUserList});
|
||||||
|
}).catch((error) => {
|
||||||
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
|
toaster.danger(errMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isAddUserDialogOpen, orgName } = this.state;
|
const { isAddUserDialogOpen, orgName } = this.state;
|
||||||
return (
|
return (
|
||||||
@@ -331,6 +363,7 @@ class OrgUsers extends Component {
|
|||||||
errorMsg={this.state.errorMsg}
|
errorMsg={this.state.errorMsg}
|
||||||
items={this.state.userList}
|
items={this.state.userList}
|
||||||
updateStatus={this.updateStatus}
|
updateStatus={this.updateStatus}
|
||||||
|
updateMembership={this.updateMembership}
|
||||||
deleteUser={this.deleteUser}
|
deleteUser={this.deleteUser}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -61,6 +61,8 @@ def get_org_user_info(org_id, user_obj):
|
|||||||
if last_login:
|
if last_login:
|
||||||
user_info['last_login'] = datetime_to_isoformat_timestr(last_login)
|
user_info['last_login'] = datetime_to_isoformat_timestr(last_login)
|
||||||
|
|
||||||
|
user_info['is_org_staff'] = True if ccnet_api.is_org_staff(org_id, email) == 1 else False
|
||||||
|
|
||||||
return user_info
|
return user_info
|
||||||
|
|
||||||
def check_org_user(func):
|
def check_org_user(func):
|
||||||
@@ -352,6 +354,28 @@ class AdminOrgUser(APIView):
|
|||||||
|
|
||||||
seafile_api.set_org_user_quota(org_id, email, user_quota)
|
seafile_api.set_org_user_quota(org_id, email, user_quota)
|
||||||
|
|
||||||
|
# update is_org_staff
|
||||||
|
is_org_staff = request.data.get("is_org_staff", '')
|
||||||
|
if is_org_staff:
|
||||||
|
|
||||||
|
is_org_staff = is_org_staff.lower()
|
||||||
|
if is_org_staff not in ('true', 'false'):
|
||||||
|
error_msg = 'is_org_staff invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
if is_org_staff == 'true':
|
||||||
|
if ccnet_api.is_org_staff(org_id, email):
|
||||||
|
error_msg = '%s is already organization staff.' % email
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
ccnet_api.set_org_staff(org_id, email)
|
||||||
|
else:
|
||||||
|
if not ccnet_api.is_org_staff(org_id, email):
|
||||||
|
error_msg = '%s is not organization staff.' % email
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
ccnet_api.unset_org_staff(org_id, email)
|
||||||
|
|
||||||
user_info = get_org_user_info(org_id, user)
|
user_info = get_org_user_info(org_id, user)
|
||||||
user_info['active'] = user.is_active
|
user_info['active'] = user.is_active
|
||||||
return Response(user_info)
|
return Response(user_info)
|
||||||
|
Reference in New Issue
Block a user