mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-07 01:41:39 +00:00
clean orphan share/upload links (#5383)
* clean orphan share/upload links * update style * [share admin - links] fixup & improvements for 'deleted' tip & 'clean orphan links' --------- Co-authored-by: llj <lingjun.li1@gmail.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from '@gatsbyjs/reach-router';
|
||||
import moment from 'moment';
|
||||
import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap';
|
||||
import { Dropdown, DropdownToggle, DropdownItem, Button } from 'reactstrap';
|
||||
import { gettext, siteRoot, canGenerateShareLink } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
@@ -10,6 +11,15 @@ import Loading from '../../components/loading';
|
||||
import EmptyTip from '../../components/empty-tip';
|
||||
import UploadLink from '../../models/upload-link';
|
||||
import ShareAdminLink from '../../components/dialog/share-admin-link';
|
||||
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
||||
|
||||
const contentPropTypes = {
|
||||
loading: PropTypes.bool.isRequired,
|
||||
errorMsg: PropTypes.string.isRequired,
|
||||
items: PropTypes.array.isRequired,
|
||||
onRemoveLink: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class Content extends Component {
|
||||
|
||||
@@ -63,6 +73,14 @@ class Content extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
Content.propTypes = contentPropTypes;
|
||||
|
||||
const itemPropTypes = {
|
||||
isDesktop: PropTypes.bool.isRequired,
|
||||
item: PropTypes.object.isRequired,
|
||||
onRemoveLink: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class Item extends Component {
|
||||
|
||||
constructor(props) {
|
||||
@@ -122,10 +140,11 @@ class Item extends Component {
|
||||
const repoUrl = `${siteRoot}library/${item.repo_id}/${encodeURIComponent(item.repo_name)}`;
|
||||
const objUrl = `${repoUrl}${Utils.encodePath(item.path)}`;
|
||||
|
||||
const deletedTip = item.obj_id === '' ? <span style={{color:'red'}}>{gettext('(deleted)')}</span> : null;
|
||||
const desktopItem = (
|
||||
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
|
||||
<td><img src={iconUrl} alt="" width="24" /></td>
|
||||
<td><Link to={objUrl}>{item.obj_name}</Link></td>
|
||||
<td><Link to={objUrl}>{item.obj_name}</Link>{deletedTip}</td>
|
||||
<td><Link to={repoUrl}>{item.repo_name}</Link></td>
|
||||
<td>{item.view_cnt}</td>
|
||||
<td>{this.renderExpiration()}</td>
|
||||
@@ -180,11 +199,19 @@ class Item extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
Item.propTypes = itemPropTypes;
|
||||
|
||||
const propTypes = {
|
||||
onShowSidePanel: PropTypes.func.isRequired,
|
||||
onSearchedClick: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class ShareAdminUploadLinks extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isCleanOrphanUploadLinksDialogOpen: false,
|
||||
loading: true,
|
||||
errorMsg: '',
|
||||
items: []
|
||||
@@ -192,6 +219,10 @@ class ShareAdminUploadLinks extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.listUserUploadLinks();
|
||||
}
|
||||
|
||||
listUserUploadLinks() {
|
||||
seafileAPI.listUserUploadLinks().then((res) => {
|
||||
let items = res.data.map(item => {
|
||||
return new UploadLink(item);
|
||||
@@ -222,30 +253,64 @@ class ShareAdminUploadLinks extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
toggleCleanOrphanUploadLinksDialog = () => {
|
||||
this.setState({isCleanOrphanUploadLinksDialogOpen: !this.state.isCleanOrphanUploadLinksDialogOpen});
|
||||
}
|
||||
|
||||
cleanOrphanUploadLinks = () => {
|
||||
seafileAPI.cleanOrphanUploadLinks().then(res => {
|
||||
const newItems = this.state.items.filter(item => item.obj_id !== '');
|
||||
this.setState({items: newItems});
|
||||
toaster.success(gettext('Successfully cleaned orphan upload links.'));
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="main-panel-center">
|
||||
<div className="cur-view-container">
|
||||
<div className="cur-view-path share-upload-nav">
|
||||
<ul className="nav">
|
||||
{canGenerateShareLink && (
|
||||
<li className="nav-item"><Link to={`${siteRoot}share-admin-share-links/`} className="nav-link">{gettext('Share Links')}</Link></li>
|
||||
)}
|
||||
<li className="nav-item"><Link to={`${siteRoot}share-admin-upload-links/`} className="nav-link active">{gettext('Upload Links')}</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="cur-view-content">
|
||||
<Content
|
||||
loading={this.state.loading}
|
||||
errorMsg={this.state.errorMsg}
|
||||
items={this.state.items}
|
||||
onRemoveLink={this.onRemoveLink}
|
||||
/>
|
||||
<Fragment>
|
||||
<TopToolbar
|
||||
onShowSidePanel={this.props.onShowSidePanel}
|
||||
onSearchedClick={this.props.onSearchedClick}
|
||||
>
|
||||
<Button className="operation-item d-none d-md-block" onClick={this.toggleCleanOrphanUploadLinksDialog}>{gettext('Clean orphan upload links')}</Button>
|
||||
</TopToolbar>
|
||||
<div className="main-panel-center">
|
||||
<div className="cur-view-container">
|
||||
<div className="cur-view-path share-upload-nav">
|
||||
<ul className="nav">
|
||||
{canGenerateShareLink && (
|
||||
<li className="nav-item"><Link to={`${siteRoot}share-admin-share-links/`} className="nav-link">{gettext('Share Links')}</Link></li>
|
||||
)}
|
||||
<li className="nav-item"><Link to={`${siteRoot}share-admin-upload-links/`} className="nav-link active">{gettext('Upload Links')}</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="cur-view-content">
|
||||
<Content
|
||||
loading={this.state.loading}
|
||||
errorMsg={this.state.errorMsg}
|
||||
items={this.state.items}
|
||||
onRemoveLink={this.onRemoveLink}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.state.isCleanOrphanUploadLinksDialogOpen &&
|
||||
<CommonOperationConfirmationDialog
|
||||
title={gettext('Clean orphan upload links')}
|
||||
message={gettext('Are you sure you want to clean orphan upload links?')}
|
||||
executeOperation={this.cleanOrphanUploadLinks}
|
||||
confirmBtnText={gettext('Clean')}
|
||||
toggleDialog={this.toggleCleanOrphanUploadLinksDialog}
|
||||
/>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ShareAdminUploadLinks.propTypes = propTypes;
|
||||
|
||||
export default ShareAdminUploadLinks;
|
||||
|
Reference in New Issue
Block a user