diff --git a/frontend/src/components/dialog/set-org-user-default-quota.js b/frontend/src/components/dialog/set-org-user-default-quota.js new file mode 100644 index 0000000000..7af424fe34 --- /dev/null +++ b/frontend/src/components/dialog/set-org-user-default-quota.js @@ -0,0 +1,88 @@ +import React from 'react'; + +import PropTypes from 'prop-types'; +import { Modal, ModalHeader, ModalBody, ModalFooter, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap'; +import { gettext } from '../../utils/constants'; +import { seafileAPI } from '../../utils/seafile-api'; +import { Utils } from '../../utils/utils'; + +const propTypes = { + orgID: PropTypes.string, + userDefaultQuota: PropTypes.number.isRequired, + updateQuota: PropTypes.func.isRequired, + toggleDialog: PropTypes.func.isRequired +}; + +class SetOrgUserDefaultQuota extends React.Component { + + constructor(props) { + super(props); + const initialQuota = this.props.userDefaultQuota < 0 ? '' : this.props.userDefaultQuota / (1000 * 1000); + this.state = { + inputValue: initialQuota, + submitBtnDisabled: false + }; + } + + handleInputChange = (e) => { + this.setState({ + inputValue: e.target.value + }); + }; + + formSubmit = () => { + const { orgID } = this.props; + const quota = this.state.inputValue.trim(); + + if (!quota) { + this.setState({ + formErrorMsg: gettext('It is required.') + }); + return false; + } + + this.setState({ + submitBtnDisabled: true + }); + + seafileAPI.orgAdminSetOrgUserDefaultQuota(orgID, quota).then((res) => { + this.props.updateQuota(res.data.user_default_quota); + this.props.toggleDialog(); + }).catch((error) => { + let errorMsg = Utils.getErrorMsg(error); + this.setState({ + formErrorMsg: errorMsg, + submitBtnDisabled: false + }); + }); + }; + + render() { + const { inputValue, formErrorMsg, submitBtnDisabled } = this.state; + return ( + + {gettext('Set user default quota')} + + + + + + MB + + +

{gettext('Tip: 0 means default limit')}

+ {formErrorMsg &&

{formErrorMsg}

} +
+
+ + + + +
+ ); + } +} + +SetOrgUserDefaultQuota.propTypes = propTypes; + +export default SetOrgUserDefaultQuota; diff --git a/frontend/src/pages/org-admin/org-info.js b/frontend/src/pages/org-admin/org-info.js index f6d1450fd8..5dbf01dcac 100644 --- a/frontend/src/pages/org-admin/org-info.js +++ b/frontend/src/pages/org-admin/org-info.js @@ -3,9 +3,11 @@ import { seafileAPI } from '../../utils/seafile-api'; import { mediaUrl, gettext, orgMemberQuotaEnabled } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import MainPanelTopbar from './main-panel-topbar'; - +import SetOrgUserDefaultQuota from '../../components/dialog/set-org-user-default-quota'; import '../../css/org-admin-info-page.css'; +const { orgID } = window.org.pageOptions; + class OrgInfo extends Component { constructor(props) { @@ -14,6 +16,8 @@ class OrgInfo extends Component { org_name: '', storage_quota: 0, storage_usage: 0, + isSetUserDefaultQuotaDialogOpen: false, + user_default_quota: 0, member_quota: 0, member_usage: 0, active_members: 0 @@ -25,21 +29,33 @@ class OrgInfo extends Component { const { org_id, org_name, member_quota, member_usage, active_members, - storage_quota, storage_usage + storage_quota, storage_usage, user_default_quota } = res.data; this.setState({ org_id, org_name, member_quota, member_usage, active_members, - storage_quota, storage_usage + storage_quota, storage_usage, user_default_quota }); }); } + toggleSetUserDefaultQuotaDialog = () => { + this.setState({ + isSetUserDefaultQuotaDialogOpen: !this.state.isSetUserDefaultQuotaDialogOpen + }); + }; + + updateQuota = (quota) => { + this.setState({ + user_default_quota: quota + }); + }; + render() { const { org_id, org_name, member_quota, member_usage, active_members, - storage_quota, storage_usage + storage_quota, storage_usage, user_default_quota } = this.state; return ( @@ -104,10 +120,29 @@ class OrgInfo extends Component {

{Utils.bytesToSize(storage_usage)}

)} + +
+

{gettext('User default quota')}

+ {Utils.bytesToSize(user_default_quota)} + + + +
+ {this.state.isSetUserDefaultQuotaDialogOpen && + + }
); } diff --git a/seahub/organizations/api/admin/info.py b/seahub/organizations/api/admin/info.py index db56b794a0..71f70cd5e3 100644 --- a/seahub/organizations/api/admin/info.py +++ b/seahub/organizations/api/admin/info.py @@ -17,6 +17,7 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication from seahub.organizations.models import OrgMemberQuota, FORCE_ADFS_LOGIN +from seahub.utils.file_size import get_file_size_unit from seahub.organizations.settings import ORG_MEMBER_QUOTA_ENABLED, \ ORG_ENABLE_ADMIN_CUSTOM_NAME from seahub.organizations.api.permissions import IsOrgAdmin @@ -41,6 +42,13 @@ def get_org_info(request, org_id): logger.error(e) storage_usage = 0 + # user default quota + try: + user_default_quota = seafile_api.get_org_user_default_quota(org_id) + except Exception as e: + logger.error(e) + user_default_quota = 0 + # member quota if ORG_MEMBER_QUOTA_ENABLED: member_quota = OrgMemberQuota.objects.get_quota(org_id) @@ -71,6 +79,7 @@ def get_org_info(request, org_id): info[FORCE_ADFS_LOGIN] = False info['storage_quota'] = storage_quota info['storage_usage'] = storage_usage + info['user_default_quota'] = user_default_quota info['member_quota'] = member_quota info['member_usage'] = member_usage info['active_members'] = active_members @@ -102,6 +111,8 @@ class OrgAdminInfo(APIView): """Update info of an organization """ + org_id = request.user.org.org_id + new_name = request.data.get('org_name', None) if new_name: @@ -109,9 +120,20 @@ class OrgAdminInfo(APIView): error_msg = _('Feature is not enabled.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - org_id = request.user.org.org_id ccnet_api.set_org_name(org_id, new_name) + user_default_quota = request.data.get('user_default_quota', None) + if user_default_quota: + + try: + user_default_quota = int(user_default_quota) + except ValueError: + error_msg = 'user_default_quota invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + user_default_quota = int(user_default_quota) * get_file_size_unit('MB') + seafile_api.set_org_user_default_quota(org_id, user_default_quota) + info = get_org_info(request, org_id) info['org_id'] = org_id info['org_name'] = new_name