mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-17 07:41:26 +00:00
update org admin settings page (#5398)
This commit is contained in:
@@ -12,7 +12,7 @@ import OrgStatisticReport from './statistic/statistic-reports';
|
|||||||
import OrgDesktopDevices from './devices/desktop-devices.js';
|
import OrgDesktopDevices from './devices/desktop-devices.js';
|
||||||
import OrgMobileDevices from './devices/mobile-devices.js';
|
import OrgMobileDevices from './devices/mobile-devices.js';
|
||||||
import OrgDevicesErrors from './devices/devices-errors.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 OrgUsers from './org-users-users';
|
||||||
import OrgUsersSearchUsers from './org-users-search-users';
|
import OrgUsersSearchUsers from './org-users-search-users';
|
||||||
import OrgAdmins from './org-users-admins';
|
import OrgAdmins from './org-users-admins';
|
||||||
@@ -26,7 +26,6 @@ import OrgGroupRepos from './org-group-repos';
|
|||||||
import OrgGroupMembers from './org-group-members';
|
import OrgGroupMembers from './org-group-members';
|
||||||
import OrgLibraries from './org-libraries';
|
import OrgLibraries from './org-libraries';
|
||||||
import OrgInfo from './org-info';
|
import OrgInfo from './org-info';
|
||||||
import OrgSettings from './org-web-settings';
|
|
||||||
import OrgLinks from './org-links';
|
import OrgLinks from './org-links';
|
||||||
import OrgDepartments from './org-departments';
|
import OrgDepartments from './org-departments';
|
||||||
import OrgDepartmentsList from './org-departments-list';
|
import OrgDepartmentsList from './org-departments-list';
|
||||||
@@ -87,7 +86,6 @@ class Org extends React.Component {
|
|||||||
<div className="main-panel">
|
<div className="main-panel">
|
||||||
<Router className="reach-router">
|
<Router className="reach-router">
|
||||||
<OrgInfo path={siteRoot + 'org/info/'} />
|
<OrgInfo path={siteRoot + 'org/info/'} />
|
||||||
<OrgSettings path={siteRoot + 'org/settings/'} />
|
|
||||||
<OrgStatisticFile path={siteRoot + 'org/statistics-admin/file/'} />
|
<OrgStatisticFile path={siteRoot + 'org/statistics-admin/file/'} />
|
||||||
<OrgStatisticStorage path={siteRoot + 'org/statistics-admin/total-storage/'} />
|
<OrgStatisticStorage path={siteRoot + 'org/statistics-admin/total-storage/'} />
|
||||||
<OrgStatisticUsers path={siteRoot + 'org/statistics-admin/active-users/'} />
|
<OrgStatisticUsers path={siteRoot + 'org/statistics-admin/active-users/'} />
|
||||||
@@ -96,7 +94,7 @@ class Org extends React.Component {
|
|||||||
<OrgDesktopDevices path={siteRoot + 'org/deviceadmin/desktop-devices/'} />
|
<OrgDesktopDevices path={siteRoot + 'org/deviceadmin/desktop-devices/'} />
|
||||||
<OrgMobileDevices path={siteRoot + 'org/deviceadmin/mobile-devices/'} />
|
<OrgMobileDevices path={siteRoot + 'org/deviceadmin/mobile-devices/'} />
|
||||||
<OrgDevicesErrors path={siteRoot + 'org/deviceadmin/devices-errors/'} />
|
<OrgDevicesErrors path={siteRoot + 'org/deviceadmin/devices-errors/'} />
|
||||||
<WebSettings path={siteRoot + 'org/web-settings'} />
|
<OrgWebSettings path={siteRoot + 'org/web-settings'} />
|
||||||
<OrgUsers path={siteRoot + 'org/useradmin'} />
|
<OrgUsers path={siteRoot + 'org/useradmin'} />
|
||||||
<OrgUsersSearchUsers path={siteRoot + 'org/useradmin/search-users'} />
|
<OrgUsersSearchUsers path={siteRoot + 'org/useradmin/search-users'} />
|
||||||
<OrgAdmins path={siteRoot + 'org/useradmin/admins/'} />
|
<OrgAdmins path={siteRoot + 'org/useradmin/admins/'} />
|
||||||
|
@@ -38,12 +38,6 @@ class SidePanel extends React.Component {
|
|||||||
<span className="nav-text">{gettext('Info')}</span>
|
<span className="nav-text">{gettext('Info')}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</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">
|
<li className="nav-item">
|
||||||
<Link className={`nav-link ellipsis ${this.getActiveClass('statistics-admin')}`} to={siteRoot + 'org/statistics-admin/file/'} onClick={() => this.tabItemClick('statistics-admin')} >
|
<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>
|
<span className="sf2-icon-histogram"></span>
|
||||||
|
@@ -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;
|
|
@@ -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;
|
|
@@ -12,7 +12,7 @@ import CheckboxItem from './checkbox-item';
|
|||||||
|
|
||||||
import '../../../css/system-admin-web-settings.css';
|
import '../../../css/system-admin-web-settings.css';
|
||||||
|
|
||||||
class WebSettings extends Component {
|
class OrgWebSettings extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -21,6 +21,7 @@ class WebSettings extends Component {
|
|||||||
errorMsg: '',
|
errorMsg: '',
|
||||||
config_dict: null,
|
config_dict: null,
|
||||||
logoPath: mediaUrl + logoPath,
|
logoPath: mediaUrl + logoPath,
|
||||||
|
file_ext_white_list: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +29,8 @@ class WebSettings extends Component {
|
|||||||
seafileAPI.orgAdminGetOrgInfo().then((res) => {
|
seafileAPI.orgAdminGetOrgInfo().then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
config_dict: res.data
|
config_dict: res.data,
|
||||||
|
file_ext_white_list: res.data.file_ext_white_list
|
||||||
});
|
});
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
this.setState({
|
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() {
|
render() {
|
||||||
const { loading, errorMsg, config_dict, logoPath } = this.state;
|
const { loading, errorMsg, config_dict, logoPath, file_ext_white_list } = this.state;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<MainPanelTopbar {...this.props} />
|
<MainPanelTopbar {...this.props} />
|
||||||
@@ -101,6 +115,17 @@ class WebSettings extends Component {
|
|||||||
}
|
}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</Section>
|
</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>
|
</Fragment>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -111,4 +136,4 @@ class WebSettings extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WebSettings;
|
export default OrgWebSettings;
|
||||||
|
@@ -59,12 +59,15 @@ def get_org_info(request, org_id):
|
|||||||
member_usage = len(org_members)
|
member_usage = len(org_members)
|
||||||
active_members = len([m for m in org_members if m.is_active])
|
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 = {}
|
||||||
info['storage_quota'] = storage_quota
|
info['storage_quota'] = storage_quota
|
||||||
info['storage_usage'] = storage_usage
|
info['storage_usage'] = storage_usage
|
||||||
info['member_quota'] = member_quota
|
info['member_quota'] = member_quota
|
||||||
info['member_usage'] = member_usage
|
info['member_usage'] = member_usage
|
||||||
info['active_members'] = active_members
|
info['active_members'] = active_members
|
||||||
|
info['file_ext_white_list'] = file_ext_white_list
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user