1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-17 15:53:28 +00:00

[shared dir view] added 'download selected items' (#4535)

This commit is contained in:
llj
2020-04-18 18:10:53 +08:00
committed by GitHub
parent 9acfef9fc8
commit 91e45db4d9
2 changed files with 87 additions and 9 deletions

View File

@@ -31,9 +31,14 @@ class ZipDownloadDialog extends React.Component {
componentDidMount() { componentDidMount() {
const { token, path, repoID, target } = this.props; const { token, path, repoID, target } = this.props;
const getZipTask = token ? let getZipTask;
seafileAPI.getShareLinkZipTask(token, path) : if (token) {
seafileAPI.zipDownload(repoID, path, target); getZipTask = target.length ?
seafileAPI.getShareLinkDirentsZipTask(token, path, target) :
seafileAPI.getShareLinkZipTask(token, path);
} else {
getZipTask = seafileAPI.zipDownload(repoID, path, target);
}
getZipTask.then((res) => { getZipTask.then((res) => {
const zipToken = res.data['zip_token']; const zipToken = res.data['zip_token'];
this.setState({ this.setState({

View File

@@ -1,4 +1,4 @@
import React from 'react'; import React, { Fragment } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Button, Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import { Button, Dropdown, DropdownToggle, DropdownItem } from 'reactstrap';
import moment from 'moment'; import moment from 'moment';
@@ -29,6 +29,9 @@ class SharedDirView extends React.Component {
errorMsg: '', errorMsg: '',
items: [], items: [],
isAllItemsSelected: false,
selectedItems: [],
sortBy: 'name', // 'name' or 'time' or 'size' sortBy: 'name', // 'name' or 'time' or 'size'
sortOrder: 'asc', // 'asc' or 'desc' sortOrder: 'asc', // 'asc' or 'desc'
@@ -49,7 +52,10 @@ class SharedDirView extends React.Component {
} }
seafileAPI.listSharedDir(token, path, thumbnailSize).then((res) => { seafileAPI.listSharedDir(token, path, thumbnailSize).then((res) => {
const items = res.data['dirent_list']; const items = res.data['dirent_list'].map(item => {
item.isSelected = false;
return item;
});
this.setState({ this.setState({
isLoading: false, isLoading: false,
errorMsg: '', errorMsg: '',
@@ -129,10 +135,20 @@ class SharedDirView extends React.Component {
}); });
} }
zipDownloadSelectedItems = () => {
this.setState({
isZipDialogOpen: true,
zipFolderPath: path,
selectedItems: this.state.items.filter(item => item.isSelected)
.map(item => item.file_name || item.folder_name)
});
}
closeZipDialog = () => { closeZipDialog = () => {
this.setState({ this.setState({
isZipDialogOpen: false, isZipDialogOpen: false,
zipFolderPath: '' zipFolderPath: '',
selectedItems: []
}); });
} }
@@ -192,6 +208,31 @@ class SharedDirView extends React.Component {
})); }));
} }
toggleAllSelected = () => {
this.setState((prevState) => ({
isAllItemsSelected: !prevState.isAllItemsSelected,
items: this.state.items.map((item) => {
item.isSelected = !prevState.isAllItemsSelected;
return item;
})
}));
}
toggleItemSelected = (targetItem, isSelected) => {
this.setState({
items: this.state.items.map((item) => {
if (item === targetItem) {
item.isSelected = isSelected;
}
return item;
})
}, () => {
this.setState({
isAllItemsSelected: !this.state.items.some(item => !item.isSelected)
});
});
}
render() { render() {
const isDesktop = Utils.isDesktop(); const isDesktop = Utils.isDesktop();
const modeBaseClass = 'btn btn-secondary btn-icon sf-view-mode-btn'; const modeBaseClass = 'btn btn-secondary btn-icon sf-view-mode-btn';
@@ -218,8 +259,13 @@ class SharedDirView extends React.Component {
</div> </div>
} }
{showDownloadIcon && {showDownloadIcon &&
<Fragment>
{this.state.items.some(item => item.isSelected) ?
<Button color="success" onClick={this.zipDownloadSelectedItems} className="ml-2 zip-btn">{gettext('ZIP Selected Items')}</Button> :
<Button color="success" onClick={this.zipDownloadFolder.bind(this, path)} className="ml-2 zip-btn">{gettext('ZIP')}</Button> <Button color="success" onClick={this.zipDownloadFolder.bind(this, path)} className="ml-2 zip-btn">{gettext('ZIP')}</Button>
} }
</Fragment>
}
</div> </div>
</div> </div>
<Content <Content
@@ -230,6 +276,9 @@ class SharedDirView extends React.Component {
sortBy={this.state.sortBy} sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder} sortOrder={this.state.sortOrder}
sortItems={this.sortItems} sortItems={this.sortItems}
isAllItemsSelected={this.state.isAllItemsSelected}
toggleAllSelected={this.toggleAllSelected}
toggleItemSelected={this.toggleItemSelected}
zipDownloadFolder={this.zipDownloadFolder} zipDownloadFolder={this.zipDownloadFolder}
showImagePopup={this.showImagePopup} showImagePopup={this.showImagePopup}
/> />
@@ -241,6 +290,7 @@ class SharedDirView extends React.Component {
<ZipDownloadDialog <ZipDownloadDialog
token={token} token={token}
path={this.state.zipFolderPath} path={this.state.zipFolderPath}
target={this.state.selectedItems}
toggleDialog={this.closeZipDialog} toggleDialog={this.closeZipDialog}
/> />
</ModalPortal> </ModalPortal>
@@ -263,6 +313,10 @@ class SharedDirView extends React.Component {
class Content extends React.Component { class Content extends React.Component {
constructor(props) {
super(props);
}
sortByName = (e) => { sortByName = (e) => {
e.preventDefault(); e.preventDefault();
const sortBy = 'name'; const sortBy = 'name';
@@ -285,7 +339,12 @@ class Content extends React.Component {
} }
render() { render() {
const { isDesktop, isLoading, errorMsg, items, sortBy, sortOrder } = this.props; const {
isDesktop,
isLoading, errorMsg, items,
sortBy, sortOrder,
isAllItemsSelected
} = this.props;
if (isLoading) { if (isLoading) {
return <Loading />; return <Loading />;
@@ -304,6 +363,7 @@ class Content extends React.Component {
item={item} item={item}
zipDownloadFolder={this.props.zipDownloadFolder} zipDownloadFolder={this.props.zipDownloadFolder}
showImagePopup={this.props.showImagePopup} showImagePopup={this.props.showImagePopup}
toggleItemSelected={this.props.toggleItemSelected}
/>; />;
})} })}
</tbody> </tbody>
@@ -329,8 +389,11 @@ class Content extends React.Component {
<table className="table-hover"> <table className="table-hover">
<thead> <thead>
<tr> <tr>
<th width="3%" className="text-center">
<input type="checkbox" checked={isAllItemsSelected} onChange={this.props.toggleAllSelected} />
</th>
<th width="5%"></th> <th width="5%"></th>
<th width="55%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortBy == 'name' && sortIcon}</a></th> <th width="52%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortBy == 'name' && sortIcon}</a></th>
<th width="14%"><a className="d-block table-sort-op" href="#" onClick={this.sortBySize}>{gettext('Size')} {sortBy == 'size' && sortIcon}</a></th> <th width="14%"><a className="d-block table-sort-op" href="#" onClick={this.sortBySize}>{gettext('Size')} {sortBy == 'size' && sortIcon}</a></th>
<th width="16%"><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortBy == 'time' && sortIcon}</a></th> <th width="16%"><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortBy == 'time' && sortIcon}</a></th>
<th width="10%"></th> <th width="10%"></th>
@@ -390,6 +453,10 @@ class Item extends React.Component {
this.props.showImagePopup(item); this.props.showImagePopup(item);
} }
toggleItemSelected = (e) => {
this.props.toggleItemSelected(this.props.item, e.target.checked);
}
render() { render() {
const { item, isDesktop } = this.props; const { item, isDesktop } = this.props;
const { isIconShown } = this.state; const { isIconShown } = this.state;
@@ -397,6 +464,9 @@ class Item extends React.Component {
if (item.is_dir) { if (item.is_dir) {
return isDesktop ? ( return isDesktop ? (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}> <tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
<td className="text-center">
<input type="checkbox" checked={item.isSelected} onChange={this.toggleItemSelected} />
</td>
<td className="text-center"><img src={Utils.getFolderIconUrl()} alt="" width="24" /></td> <td className="text-center"><img src={Utils.getFolderIconUrl()} alt="" width="24" /></td>
<td> <td>
<a href={`?p=${encodeURIComponent(item.folder_path.substr(0, item.folder_path.length - 1))}&mode=${mode}`}>{item.folder_name}</a> <a href={`?p=${encodeURIComponent(item.folder_path.substr(0, item.folder_path.length - 1))}&mode=${mode}`}>{item.folder_name}</a>
@@ -444,6 +514,9 @@ class Item extends React.Component {
const thumbnailURL = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : ''; const thumbnailURL = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : '';
return isDesktop ? ( return isDesktop ? (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}> <tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
<td className="text-center">
<input type="checkbox" checked={item.isSelected} onChange={this.toggleItemSelected} />
</td>
<td className="text-center"> <td className="text-center">
{thumbnailURL ? {thumbnailURL ?
<img className="thumbnail" src={thumbnailURL} alt="" /> : <img className="thumbnail" src={thumbnailURL} alt="" /> :