1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-16 07:08:55 +00:00

update org admin settings page (#5398)

This commit is contained in:
lian
2023-03-11 13:07:00 +08:00
committed by GitHub
parent 397afa816b
commit 7c87378bd0
6 changed files with 34 additions and 132 deletions

View File

@@ -12,7 +12,7 @@ import OrgStatisticReport from './statistic/statistic-reports';
import OrgDesktopDevices from './devices/desktop-devices.js';
import OrgMobileDevices from './devices/mobile-devices.js';
import OrgDevicesErrors from './devices/devices-errors.js';
import WebSettings from './web-settings/web-settings';
import OrgWebSettings from './web-settings/web-settings';
import OrgUsers from './org-users-users';
import OrgUsersSearchUsers from './org-users-search-users';
import OrgAdmins from './org-users-admins';
@@ -26,7 +26,6 @@ import OrgGroupRepos from './org-group-repos';
import OrgGroupMembers from './org-group-members';
import OrgLibraries from './org-libraries';
import OrgInfo from './org-info';
import OrgSettings from './org-web-settings';
import OrgLinks from './org-links';
import OrgDepartments from './org-departments';
import OrgDepartmentsList from './org-departments-list';
@@ -87,7 +86,6 @@ class Org extends React.Component {
<div className="main-panel">
<Router className="reach-router">
<OrgInfo path={siteRoot + 'org/info/'} />
<OrgSettings path={siteRoot + 'org/settings/'} />
<OrgStatisticFile path={siteRoot + 'org/statistics-admin/file/'} />
<OrgStatisticStorage path={siteRoot + 'org/statistics-admin/total-storage/'} />
<OrgStatisticUsers path={siteRoot + 'org/statistics-admin/active-users/'} />
@@ -96,7 +94,7 @@ class Org extends React.Component {
<OrgDesktopDevices path={siteRoot + 'org/deviceadmin/desktop-devices/'} />
<OrgMobileDevices path={siteRoot + 'org/deviceadmin/mobile-devices/'} />
<OrgDevicesErrors path={siteRoot + 'org/deviceadmin/devices-errors/'} />
<WebSettings path={siteRoot + 'org/web-settings'} />
<OrgWebSettings path={siteRoot + 'org/web-settings'} />
<OrgUsers path={siteRoot + 'org/useradmin'} />
<OrgUsersSearchUsers path={siteRoot + 'org/useradmin/search-users'} />
<OrgAdmins path={siteRoot + 'org/useradmin/admins/'} />

View File

@@ -38,12 +38,6 @@ class SidePanel extends React.Component {
<span className="nav-text">{gettext('Info')}</span>
</Link>
</li>
<li className="nav-item">
<Link className={`nav-link ellipsis ${this.getActiveClass('settings')}`} to={siteRoot + 'org/settings/'} onClick={() => this.tabItemClick('settings')} >
<span className="sf2-icon-cog2"></span>
<span className="nav-text">{gettext('Settings')}</span>
</Link>
</li>
<li className="nav-item">
<Link className={`nav-link ellipsis ${this.getActiveClass('statistics-admin')}`} to={siteRoot + 'org/statistics-admin/file/'} onClick={() => this.tabItemClick('statistics-admin')} >
<span className="sf2-icon-histogram"></span>

View File

@@ -1,42 +0,0 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Row, Col, Label } from 'reactstrap';
const propTypes = {
displayName: PropTypes.string.isRequired,
helpTip: PropTypes.string,
mainContent: PropTypes.object.isRequired,
extraContent: PropTypes.object
};
class SettingItemBase extends Component {
constructor(props) {
super(props);
}
render() {
const { helpTip, displayName, mainContent, extraContent } = this.props;
return (
<Fragment>
<Row className="my-4">
<Col md="3">
<Label className="web-setting-label">{displayName}</Label>
</Col>
<Col md="5">
{mainContent}
{helpTip && <p className="small text-secondary mt-1">{helpTip}</p>}
</Col>
<Col md="4">
{extraContent}
</Col>
</Row>
</Fragment>
);
}
}
SettingItemBase.propTypes = propTypes;
export default SettingItemBase;

View File

@@ -1,76 +0,0 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Input, Button } from 'reactstrap';
import { gettext } from '../../utils/constants';
import SettingItemBase from './web-setting-item-base';
const propTypes = {
inputType: PropTypes.string,
saveSetting: PropTypes.func.isRequired,
keyText: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string,PropTypes.number]),
helpTip: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired
};
class WebSettingInput extends Component {
constructor(props) {
super(props);
this.state = {
isBtnsShown: false,
value: this.props.value
};
}
toggleBtns = () => {
this.setState({isBtnsShown: !this.state.isBtnsShown});
}
hideBtns = (e) => {
if (!this.state.isBtnsShown) {
return;
}
if (this.props.value != this.state.value) {
this.setState({value: this.props.value});
}
this.toggleBtns();
}
onInputChange = (e) => {
this.setState({ value: e.target.value });
}
onSubmit = (e) => {
const value = this.state.value.trim();
if (value != this.props.value) {
this.props.saveSetting(this.props.keyText, value);
}
this.toggleBtns();
}
render() {
const { isBtnsShown, value } = this.state;
const { helpTip, displayName, inputType } = this.props;
return (
<SettingItemBase
displayName={displayName}
helpTip={helpTip}
mainContent={
<Input type={inputType || 'text'} className={inputType == 'textarea' ? 'web-setting-textarea' : ''} onChange={this.onInputChange} onFocus={this.toggleBtns} onBlur={this.hideBtns} value={value} />
}
extraContent={
isBtnsShown ?
<Fragment>
<Button className="sf2-icon-tick web-setting-icon-btn web-setting-icon-btn-submit" onMouseDown={this.onSubmit} title={gettext('Submit')}></Button>
<Button className="ml-1 sf2-icon-x2 web-setting-icon-btn web-setting-icon-btn-cancel" title={gettext('Cancel')}></Button>
</Fragment> : null
}
/>
);
}
}
WebSettingInput.propTypes = propTypes;
export default WebSettingInput;

View File

@@ -12,7 +12,7 @@ import CheckboxItem from './checkbox-item';
import '../../../css/system-admin-web-settings.css';
class WebSettings extends Component {
class OrgWebSettings extends Component {
constructor(props) {
super(props);
@@ -21,6 +21,7 @@ class WebSettings extends Component {
errorMsg: '',
config_dict: null,
logoPath: mediaUrl + logoPath,
file_ext_white_list: '',
};
}
@@ -28,7 +29,8 @@ class WebSettings extends Component {
seafileAPI.orgAdminGetOrgInfo().then((res) => {
this.setState({
loading: false,
config_dict: res.data
config_dict: res.data,
file_ext_white_list: res.data.file_ext_white_list
});
}).catch((error) => {
this.setState({
@@ -62,8 +64,20 @@ class WebSettings extends Component {
});
}
updateFileExtWhiteList = (key, value) => {
seafileAPI.orgAdminSetSysSettingInfo(orgID, key, value).then((res) => {
this.setState({
file_ext_white_list: res.data.file_ext_white_list
});
toaster.success(gettext('Success'));
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
render() {
const { loading, errorMsg, config_dict, logoPath } = this.state;
const { loading, errorMsg, config_dict, logoPath, file_ext_white_list } = this.state;
return (
<Fragment>
<MainPanelTopbar {...this.props} />
@@ -101,6 +115,17 @@ class WebSettings extends Component {
}
</Fragment>
</Section>
<Section headingText={gettext('File Upload')}>
<Fragment>
<InputItem
saveSetting={this.updateFileExtWhiteList}
displayName='file_ext_white_list'
keyText='file_ext_white_list'
value={file_ext_white_list}
helpTip={gettext('File upload format whitelist via web UI and API. For example: "md;txt;docx", empty means no limit.')}
/>
</Fragment>
</Section>
</Fragment>
}
</div>
@@ -111,4 +136,4 @@ class WebSettings extends Component {
}
}
export default WebSettings;
export default OrgWebSettings;

View File

@@ -59,12 +59,15 @@ def get_org_info(request, org_id):
member_usage = len(org_members)
active_members = len([m for m in org_members if m.is_active])
file_ext_white_list = seafile_api.org_get_file_ext_white_list(org_id)
info = {}
info['storage_quota'] = storage_quota
info['storage_usage'] = storage_usage
info['member_quota'] = member_quota
info['member_usage'] = member_usage
info['active_members'] = active_members
info['file_ext_white_list'] = file_ext_white_list
return info