1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-12 13:24:52 +00:00

file scan records page (#3051)

* file scan records page

* add file scan setting

* repair code
This commit is contained in:
王健辉
2019-03-13 16:50:30 +08:00
committed by Daniel Pan
parent 53c3791043
commit 8c81489c51
17 changed files with 611 additions and 2 deletions

View File

@@ -1,9 +1,14 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { Utils } from '../../utils/utils';
import editorUtilities from '../../utils/editor-utilties';
import { siteRoot, gettext } from '../../utils/constants';
const propTypes = {
isAdminPanel: PropTypes.bool,
};
class Account extends Component {
constructor(props) {
super(props);
@@ -87,11 +92,16 @@ class Account extends Component {
}
renderMenu = () => {
if(this.state.isStaff){
if (this.state.isStaff && !this.props.isAdminPanel) {
return (
<a href={siteRoot + 'sys/useradmin/'} title={gettext('System Admin')} className="item">{gettext('System Admin')}</a>
);
}
if (this.props.isAdminPanel) {
return (
<a href={siteRoot} title={gettext('Exit Admin Panel')} className="item">{gettext('Exit Admin Panel')}</a>
);
}
if (this.state.isOrgStaff) {
return (
<a href={siteRoot + 'org/useradmin/'} title={gettext('Organization Admin')} className="item">{gettext('Organization Admin')}</a>
@@ -143,4 +153,6 @@ class Account extends Component {
}
}
Account.propTypes = propTypes;
export default Account;

View File

@@ -0,0 +1,137 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, loginUrl } from '../../utils/constants';
const tablePropTypes = {
loading: PropTypes.bool.isRequired,
errorMsg: PropTypes.string.isRequired,
records: PropTypes.array.isRequired,
};
class Table extends Component {
render() {
let { loading, errorMsg, records } = this.props;
if (loading) {
return <span className="loading-icon loading-tip"></span>;
} else if (errorMsg) {
return <p className="error text-center">{errorMsg}</p>;
} else {
return (
<table width="100%" className="table table-hover table-vcenter">
<thead>
<tr>
<th width="16%">{gettext('Library')}</th>
<th width="30%">{gettext('ID')}</th>
<th width="30%">{gettext('Path')}</th>
<th width="12%">{gettext('Label')}</th>
<th width="12%">{gettext('Suggestion')}</th>
</tr>
</thead>
<tbody>
{records.map((record, index) => {
return (
<Item key={index} record={record} />
);
})}
</tbody>
</table>
);
}
}
}
Table.propTypes = tablePropTypes;
const itemPropTypes = {
record: PropTypes.object.isRequired,
};
class Item extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
let record = this.props.record;
return (
<tr>
<td>{record.repo_name}</td>
<td>{record.repo_id}</td>
<td>{record.path}</td>
<td>{record.detail.label}</td>
<td>{record.detail.suggestion}</td>
</tr>
);
}
}
Item.propTypes = itemPropTypes;
class FileScanRecords extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
errorMsg: '',
records: [],
};
}
componentDidMount() {
seafileAPI.listFileScanRecords().then((res) => {
this.setState({
loading: false,
records: res.data.record_list,
});
}).catch((error) => {
if (error.response) {
if (error.response.status == 403) {
this.setState({
loading: false,
errorMsg: gettext('Permission denied')
});
location.href = `${loginUrl}?next=${encodeURIComponent(location.href)}`;
} else {
this.setState({
loading: false,
errorMsg: gettext('Error')
});
}
} else {
this.setState({
loading: false,
errorMsg: gettext('Please check the network.')
});
}
});
}
render() {
return (
<div className="main-panel-center">
<div className="cur-view-container" id="content-scan-records">
<div className="cur-view-path">
<h3 className="sf-heading">{gettext('Content Scan Records')}</h3>
</div>
<div className="cur-view-content">
<Table
loading={this.state.loading}
errorMsg={this.state.errorMsg}
records={this.state.records}
/>
</div>
</div>
</div>
);
}
}
export default FileScanRecords;

View File

@@ -0,0 +1,60 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from '@reach/router';
import { siteRoot, gettext } from '../../utils/constants';
import SidePanel from './side-panel';
import MainPanel from './main-panel';
import FileScanRecords from './file-scan-records';
import '../../assets/css/fa-solid.css';
import '../../assets/css/fa-regular.css';
import '../../assets/css/fontawesome.css';
import '../../css/layout.css';
import '../../css/toolbar.css';
class SysAdmin extends React.Component {
constructor(props) {
super(props);
this.state = {
isSidePanelClosed: false,
currentTab: 'file-scan',
};
}
componentDidMount() {
let href = window.location.href.split('/');
this.setState({currentTab: href[href.length - 2]});
}
onCloseSidePanel = () => {
this.setState({isSidePanelClosed: !this.state.isSidePanelClosed});
}
tabItemClick = (param) => {
this.setState({currentTab: param});
}
render() {
let { currentTab, isSidePanelClosed, } = this.state;
return (
<div id="main">
<SidePanel isSidePanelClosed={isSidePanelClosed} onCloseSidePanel={this.onCloseSidePanel} />
<MainPanel>
<Router>
<FileScanRecords
path={siteRoot + 'sys/file-scan-records'}
currentTab={currentTab}
tabItemClick={this.tabItemClick}
/>
</Router>
</MainPanel>
</div>
);
}
}
ReactDOM.render(
<SysAdmin />,
document.getElementById('wrapper')
);

View File

@@ -0,0 +1,31 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Account from '../../components/common/account';
const propTypes = {
children: PropTypes.object.isRequired,
};
class MainPanel extends Component {
render() {
return (
<div className="main-panel o-hidden">
<div className="main-panel-north border-left-show">
<div className="cur-view-toolbar">
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu"></span>
</div>
<div className="common-toolbar">
<Account isAdminPanel={true} />
</div>
</div>
{this.props.children}
</div>
);
}
}
MainPanel.propTypes = propTypes;
export default MainPanel;

View File

@@ -0,0 +1,183 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from '@reach/router';
import Logo from '../../components/logo';
import { gettext, siteRoot, isPro, isDefaultAdmin, canViewSystemInfo, canViewStatistic,
canConfigSystem, canManageLibrary, canManageUser, canManageGroup, canViewUserLog,
canViewAdminLog, constanceEnabled, multiTenancy, multiInstitution, sysadminExtraEnabled,
enableGuestInvitation, enableTermsAndConditions, enableFileScan } from '../../utils/constants';
const propTypes = {
isSidePanelClosed: PropTypes.bool.isRequired,
onCloseSidePanel: PropTypes.func.isRequired,
};
class SidePanel extends React.Component {
render() {
return (
<div className={`side-panel ${this.props.isSidePanelClosed ? '' : 'left-zero'}`}>
<div className="side-panel-north">
<Logo onCloseSidePanel={this.props.onCloseSidePanel}/>
</div>
<div className="side-panel-center">
<div className="side-nav">
<div className="side-nav-con">
<h3 className="sf-heading">{gettext('System Admin')}</h3>
<ul className="nav nav-pills flex-column nav-container">
{canViewSystemInfo &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#dashboard/"}>
<span className="sf2-icon-info" aria-hidden="true"></span>
<span className="nav-text">{gettext('Info')}</span>
</a>
</li>
}
{isPro && canViewStatistic &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/statistic/file/"}>
<span className="sf2-icon-histogram" aria-hidden="true"></span>
<span className="nav-text">{gettext('Statistic')}</span>
</a>
</li>
}
{isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#desktop-devices/"}>
<span className="sf2-icon-monitor" aria-hidden="true"></span>
<span className="nav-text">{gettext('Devices')}</span>
</a>
</li>
}
{constanceEnabled && canConfigSystem &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/settings/"}>
<span className="sf2-icon-cog2" aria-hidden="true"></span>
<span className="nav-text">{gettext('Settings')}</span>
</a>
</li>
}
{canManageLibrary &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#all-libs/"}>
<span className="sf2-icon-library" aria-hidden="true"></span>
<span className="nav-text">{gettext('Libraries')}</span>
</a>
</li>
}
{canManageUser &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/useradmin/"}>
<span className="sf2-icon-user" aria-hidden="true"></span>
<span className="nav-text">{gettext('Users')}</span>
</a>
</li>
}
{canManageGroup &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#groups/"}>
<span className="sf2-icon-group" aria-hidden="true"></span>
<span className="nav-text">{gettext('Groups')}</span>
</a>
</li>
}
{isPro && canManageGroup &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#address-book/"}>
<span className="sf2-icon-organization" aria-hidden="true"></span>
<span className="nav-text">{gettext('Departments')}</span>
</a>
</li>
}
{multiTenancy && isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/orgadmin/"}>
<span className="sf2-icon-organization" aria-hidden="true"></span>
<span className="nav-text">{gettext('Organizations')}</span>
</a>
</li>
}
{multiInstitution && isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/instadmin/"}>
<span className="sf2-icon-organization" aria-hidden="true"></span>
<span className="nav-text">{gettext('Institutions')}</span>
</a>
</li>
}
{isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/notificationadmin/"}>
<span className="sf2-icon-msgs" aria-hidden="true"></span>
<span className="nav-text">{gettext('Notifications')}</span>
</a>
</li>
}
{isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/publinkadmin/"}>
<span className="sf2-icon-link" aria-hidden="true"></span>
<span className="nav-text">{gettext('Links')}</span>
</a>
</li>
}
{sysadminExtraEnabled && canViewUserLog &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/loginadmin/"}>
<span className="sf2-icon-clock" aria-hidden="true"></span>
<span className="nav-text">{gettext('Logs')}</span>
</a>
</li>
}
{isPro && isDefaultAdmin && enableFileScan &&
<li className="nav-item">
<Link className='nav-link ellipsis' to={siteRoot + "sys/file-scan-records/"}>
<span className="sf2-icon-security" aria-hidden="true"></span>
<span className="nav-text">{gettext('File Scan')}</span>
</Link>
</li>
}
{isPro && isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/virus_scan_records/"}>
<span className="sf2-icon-security" aria-hidden="true"></span>
<span className="nav-text">{gettext('Virus Scan')}</span>
</a>
</li>
}
{enableGuestInvitation && isDefaultAdmin &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/invitationadmin/"}>
<span className="sf2-icon-invite" aria-hidden="true"></span>
<span className="nav-text">{gettext('Invitations')}</span>
</a>
</li>
}
{isDefaultAdmin && enableTermsAndConditions &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sys/termsadmin/"}>
<span className="sf2-icon-wiki" aria-hidden="true"></span>
<span className="nav-text">{gettext('Terms and Conditions')}</span>
</a>
</li>
}
{isPro && canViewAdminLog &&
<li className="nav-item">
<a className='nav-link ellipsis' href={siteRoot + "sysadmin/#admin-operation-logs/"}>
<span className="sf2-icon-admin-log" aria-hidden="true"></span>
<span className="nav-text">{gettext('Admin Logs')}</span>
</a>
</li>
}
</ul>
</div>
</div>
</div>
</div>
);
}
}
SidePanel.propTypes = propTypes;
export default SidePanel;

View File

@@ -73,3 +73,21 @@ export const originFileExists = window.draft ? window.draft.config.originFileExi
// org admin
export const orgID = window.org ? window.org.pageOptions.orgID : '';
export const invitationLink = window.org ? window.org.pageOptions.invitationLink : '';
// sys admin
export const constanceEnabled = window.sysadmin ? window.sysadmin.pageOptions.constance_enabled : '';
export const multiTenancy = window.sysadmin ? window.sysadmin.pageOptions.multi_tenancy : '';
export const multiInstitution = window.sysadmin ? window.sysadmin.pageOptions.multi_institution : '';
export const sysadminExtraEnabled = window.sysadmin ? window.sysadmin.pageOptions.sysadmin_extra_enabled : '';
export const enableGuestInvitation = window.sysadmin ? window.sysadmin.pageOptions.enable_guest_invitation : '';
export const enableTermsAndConditions = window.sysadmin ? window.sysadmin.pageOptions.enable_terms_and_conditions : '';
export const isDefaultAdmin = window.sysadmin ? window.sysadmin.pageOptions.is_default_admin : '';
export const enableFileScan = window.sysadmin ? window.sysadmin.pageOptions.enable_file_scan : '';
export const canViewSystemInfo = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_view_system_info : '';
export const canViewStatistic = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_view_statistic : '';
export const canConfigSystem = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_config_system : '';
export const canManageLibrary = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_manage_library : '';
export const canManageUser = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_manage_user : '';
export const canManageGroup = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_manage_group : '';
export const canViewUserLog = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_view_user_log : '';
export const canViewAdminLog = window.sysadmin ? window.sysadmin.pageOptions.admin_permissions.can_view_admin_log : '';