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:
@@ -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({
|
||||||
|
@@ -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="" /> :
|
||||||
|
Reference in New Issue
Block a user