2019-10-22 11:49:30 +00:00
|
|
|
import React, { Component, Fragment } from 'react';
|
|
|
|
import { seafileAPI } from '../../../utils/seafile-api';
|
2019-12-05 07:45:16 +00:00
|
|
|
import { gettext, siteRoot } from '../../../utils/constants';
|
|
|
|
import { Utils } from '../../../utils/utils';
|
2019-10-22 11:49:30 +00:00
|
|
|
import EmptyTip from '../../../components/empty-tip';
|
|
|
|
import { Button } from 'reactstrap';
|
|
|
|
import moment from 'moment';
|
|
|
|
import Loading from '../../../components/loading';
|
|
|
|
import Paginator from '../../../components/paginator';
|
|
|
|
import LogsNav from './logs-nav';
|
|
|
|
import MainPanelTopbar from '../main-panel-topbar';
|
2019-11-07 06:17:59 +00:00
|
|
|
import UserLink from '../user-link';
|
2019-10-22 11:49:30 +00:00
|
|
|
import LogsExportExcelDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-logs-export-excel-dialog';
|
|
|
|
import ModalPortal from '../../../components/modal-portal';
|
|
|
|
|
|
|
|
|
|
|
|
class Content extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
}
|
|
|
|
|
|
|
|
getPreviousPage = () => {
|
|
|
|
this.props.getLogsByPage(this.props.currentPage - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
getNextPage = () => {
|
|
|
|
this.props.getLogsByPage(this.props.currentPage + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { loading, errorMsg, items, perPage, currentPage, hasNextPage } = this.props;
|
|
|
|
if (loading) {
|
|
|
|
return <Loading />;
|
|
|
|
} else if (errorMsg) {
|
|
|
|
return <p className="error text-center">{errorMsg}</p>;
|
|
|
|
} else {
|
|
|
|
const emptyTip = (
|
|
|
|
<EmptyTip>
|
2020-03-06 08:21:45 +00:00
|
|
|
<h2>{gettext('No file access logs')}</h2>
|
2019-10-22 11:49:30 +00:00
|
|
|
</EmptyTip>
|
|
|
|
);
|
|
|
|
const table = (
|
|
|
|
<Fragment>
|
|
|
|
<table className="table-hover">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th width="20%">{gettext('Name')}</th>
|
|
|
|
<th width="10%">{gettext('Type')}</th>
|
|
|
|
<th width="20%">{gettext('IP')}{' / '}{gettext('Device')}</th>
|
|
|
|
<th width="20%">{gettext('Date')}</th>
|
|
|
|
<th width="15%">{gettext('Library')}</th>
|
|
|
|
<th width="15%">{gettext('File')}{' / '}{gettext('Folder')}</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
{items &&
|
|
|
|
<tbody>
|
|
|
|
{items.map((item, index) => {
|
|
|
|
return (<Item
|
|
|
|
key={index}
|
|
|
|
item={item}
|
|
|
|
/>);
|
|
|
|
})}
|
|
|
|
</tbody>
|
|
|
|
}
|
|
|
|
</table>
|
|
|
|
<Paginator
|
|
|
|
gotoPreviousPage={this.getPreviousPage}
|
|
|
|
gotoNextPage={this.getNextPage}
|
|
|
|
currentPage={currentPage}
|
|
|
|
hasNextPage={hasNextPage}
|
|
|
|
curPerPage={perPage}
|
|
|
|
resetPerPage={this.props.resetPerPage}
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
return items.length ? table : emptyTip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Item extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
isOpIconShown: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMouseOver = () => {
|
|
|
|
this.setState({
|
|
|
|
isOpIconShown: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMouseOut = () => {
|
|
|
|
this.setState({
|
|
|
|
isOpIconShown: false
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
let { item } = this.props;
|
|
|
|
return (
|
|
|
|
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
|
2019-11-07 06:17:59 +00:00
|
|
|
<td><UserLink email={item.email} name={item.name} /></td>
|
2019-10-22 11:49:30 +00:00
|
|
|
<td>{item.event_type}</td>
|
|
|
|
<td>{item.ip}{' / '}{item.device}</td>
|
|
|
|
<td>{moment(item.time).fromNow()}</td>
|
|
|
|
<td>{item.repo_name ? item.repo_name : gettext('Deleted')}</td>
|
|
|
|
<td>{item.file_or_dir_name}</td>
|
|
|
|
</tr>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class FileAccessLogs extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
loading: true,
|
|
|
|
errorMsg: '',
|
|
|
|
logList: [],
|
2020-01-13 04:07:24 +00:00
|
|
|
perPage: 25,
|
2019-10-22 11:49:30 +00:00
|
|
|
currentPage: 1,
|
|
|
|
hasNextPage: false,
|
|
|
|
isExportExcelDialogOpen: false,
|
|
|
|
};
|
|
|
|
this.initPage = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleExportExcelDialog = () => {
|
|
|
|
this.setState({isExportExcelDialogOpen: !this.state.isExportExcelDialogOpen});
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount () {
|
2020-01-13 04:07:24 +00:00
|
|
|
let urlParams = (new URL(window.location)).searchParams;
|
|
|
|
const { currentPage, perPage } = this.state;
|
|
|
|
this.setState({
|
|
|
|
perPage: parseInt(urlParams.get('per_page') || perPage),
|
|
|
|
currentPage: parseInt(urlParams.get('page') || currentPage)
|
|
|
|
}, () => {
|
|
|
|
this.getLogsByPage(this.state.currentPage);
|
|
|
|
});
|
2019-10-22 11:49:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getLogsByPage = (page) => {
|
|
|
|
let { perPage } = this.state;
|
|
|
|
seafileAPI.sysAdminListFileAccessLogs(page, perPage).then((res) => {
|
|
|
|
this.setState({
|
|
|
|
logList: res.data.file_access_log_list,
|
|
|
|
loading: false,
|
|
|
|
currentPage: page,
|
|
|
|
hasNextPage: res.data.has_next_page,
|
|
|
|
});
|
|
|
|
}).catch((error) => {
|
2019-12-05 07:45:16 +00:00
|
|
|
this.setState({
|
|
|
|
loading: false,
|
|
|
|
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
|
|
|
|
});
|
2019-10-22 11:49:30 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
resetPerPage = (newPerPage) => {
|
|
|
|
this.setState({
|
|
|
|
perPage: newPerPage,
|
|
|
|
}, () => this.getLogsByPage(this.initPage));
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
let { logList, currentPage, perPage, hasNextPage, isExportExcelDialogOpen } = this.state;
|
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<MainPanelTopbar>
|
|
|
|
<Button className="btn btn-secondary operation-item" onClick={this.toggleExportExcelDialog}>{gettext('Export Excel')}</Button>
|
|
|
|
</MainPanelTopbar>
|
|
|
|
<div className="main-panel-center flex-row">
|
|
|
|
<div className="cur-view-container">
|
|
|
|
<LogsNav currentItem="fileAccessLogs" />
|
|
|
|
<div className="cur-view-content">
|
|
|
|
<Content
|
|
|
|
loading={this.state.loading}
|
|
|
|
errorMsg={this.state.errorMsg}
|
|
|
|
items={logList}
|
|
|
|
currentPage={currentPage}
|
|
|
|
perPage={perPage}
|
|
|
|
hasNextPage={hasNextPage}
|
|
|
|
getLogsByPage={this.getLogsByPage}
|
|
|
|
resetPerPage={this.resetPerPage}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{isExportExcelDialogOpen &&
|
|
|
|
<ModalPortal>
|
|
|
|
<LogsExportExcelDialog
|
|
|
|
logType={'fileAccess'}
|
|
|
|
toggle={this.toggleExportExcelDialog}
|
|
|
|
/>
|
|
|
|
</ModalPortal>
|
|
|
|
}
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default FileAccessLogs;
|