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

['share dialog' - 'Share Link', 'Share Admin' - 'Links'] share links: get limited links per request, scroll down to get more (#5840)

This commit is contained in:
llj
2023-12-20 12:01:18 +08:00
committed by GitHub
parent 53562381a8
commit bd05e05a1a
4 changed files with 103 additions and 14 deletions

View File

@@ -18,6 +18,8 @@ const propTypes = {
itemType: PropTypes.string
};
const PER_PAGE = 25;
class ShareLinkPanel extends React.Component {
constructor(props) {
@@ -28,6 +30,9 @@ class ShareLinkPanel extends React.Component {
this.state = {
isLoading: true,
hasMore: false,
isLoadingMore: false,
page: 1,
mode: 'listLinks',
sharedLinkInfo: null,
shareLinks: [],
@@ -37,11 +42,12 @@ class ShareLinkPanel extends React.Component {
}
componentDidMount() {
let path = this.props.itemPath;
let repoID = this.props.repoID;
seafileAPI.getShareLink(repoID, path).then((res) => {
const { page } = this.state;
const { repoID, itemPath: path } = this.props;
seafileAPI.listShareLinks({repoID, path, page}).then((res) => {
this.setState({
isLoading: false,
hasMore: res.data.length == PER_PAGE,
shareLinks: res.data.map(item => new ShareLink(item))
});
}).catch(error => {
@@ -184,13 +190,46 @@ class ShareLinkPanel extends React.Component {
});
};
handleScroll = (event) => {
if (!this.state.isLoadingMore && this.state.hasMore) {
const clientHeight = event.target.clientHeight;
const scrollHeight = event.target.scrollHeight;
const scrollTop = event.target.scrollTop;
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (isBottom) { // scroll to the bottom
this.setState({isLoadingMore: true}, () => {
this.getMore();
});
}
}
};
getMore = () => {
const { page, shareLinks } = this.state;
const { repoID, itemPath: path } = this.props;
seafileAPI.listShareLinks({repoID, path, page: page + 1}).then((res) => {
this.setState({
isLoadingMore: false,
hasMore: res.data.length == PER_PAGE,
page: page + 1,
shareLinks: shareLinks.concat(res.data.map(item => new ShareLink(item)))
});
}).catch(error => {
this.setState({
isLoadingMore: false
});
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
render() {
if (this.state.isLoading) {
return <Loading />;
}
const { repoID, itemPath, userPerm } = this.props;
const { mode, shareLinks, sharedLinkInfo, permissionOptions, currentPermission } = this.state;
const { mode, shareLinks, sharedLinkInfo, permissionOptions, currentPermission, isLoadingMore } = this.state;
switch (mode) {
case 'displayLinkDetails':
@@ -242,6 +281,8 @@ class ShareLinkPanel extends React.Component {
toggleSelectLink={this.toggleSelectLink}
deleteShareLinks={this.deleteShareLinks}
deleteLink={this.deleteLink}
handleScroll={this.handleScroll}
isLoadingMore={isLoadingMore}
/>
);
}

View File

@@ -4,6 +4,7 @@ import { gettext, siteRoot } from '../../utils/constants';
import EmptyTip from '../empty-tip';
import LinkItem from './link-item';
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
import Loading from '../../components/loading';
const propTypes = {
shareLinks: PropTypes.array.isRequired,
@@ -13,7 +14,9 @@ const propTypes = {
toggleSelectAllLinks: PropTypes.func.isRequired,
toggleSelectLink: PropTypes.func.isRequired,
deleteLink: PropTypes.func.isRequired,
deleteShareLinks: PropTypes.func.isRequired
deleteShareLinks: PropTypes.func.isRequired,
isLoadingMore: PropTypes.bool.isRequired,
handleScroll: PropTypes.func.isRequired
};
class LinkList extends React.Component {
@@ -46,7 +49,7 @@ class LinkList extends React.Component {
};
render() {
const { shareLinks, permissionOptions } = this.props;
const { shareLinks, permissionOptions, isLoadingMore, handleScroll } = this.props;
const selectedLinks = shareLinks.filter(item => item.isSelected);
const isAllLinksSelected = shareLinks.length == selectedLinks.length;
@@ -88,7 +91,7 @@ class LinkList extends React.Component {
</tr>
</thead>
</table>
<div className='table-real-container'>
<div className='table-real-container' onScroll={handleScroll}>
<table className="table-real-content table-thead-hidden">
<thead>
<tr>
@@ -114,6 +117,7 @@ class LinkList extends React.Component {
})}
</tbody>
</table>
{isLoadingMore && <Loading />}
</div>
</div>
)}

View File

@@ -129,10 +129,6 @@ class EditorApi {
return seafileAPI.getInternalLink(repoID, filePath);
}
getShareLink() {
return seafileAPI.getShareLink(repoID, filePath);
}
createShareLink (repoID, filePath, userPassword, userValidDays, permissions) {
return seafileAPI.createShareLink(repoID, filePath, userPassword, userValidDays, permissions);
}

View File

@@ -19,6 +19,7 @@ import Selector from '../../components/single-selector';
const contentPropTypes = {
loading: PropTypes.bool.isRequired,
isLoadingMore: PropTypes.bool.isRequired,
errorMsg: PropTypes.string.isRequired,
items: PropTypes.array.isRequired,
sortBy: PropTypes.string.isRequired,
@@ -114,7 +115,12 @@ class Content extends Component {
</table>
);
return items.length ? table : emptyTip;
return items.length ? (
<>
{table}
{this.props.isLoadingMore && <div className="flex-shrink-0"><Loading /></div>}
</>
) : emptyTip;
}
}
}
@@ -360,6 +366,8 @@ const propTypes = {
onSearchedClick: PropTypes.func.isRequired
};
const PER_PAGE = 25;
class ShareAdminShareLinks extends Component {
constructor(props) {
@@ -367,6 +375,9 @@ class ShareAdminShareLinks extends Component {
this.state = {
isCleanInvalidShareLinksDialogOpen: false,
loading: true,
hasMore: false,
isLoadingMore: false,
page: 1,
errorMsg: '',
items: [],
sortBy: 'name', // 'name' or 'time'
@@ -437,12 +448,14 @@ class ShareAdminShareLinks extends Component {
}
listUserShareLinks() {
seafileAPI.listUserShareLinks().then((res) => {
const { page } = this.state;
seafileAPI.listShareLinks({ page }).then((res) => {
let items = res.data.map(item => {
return new ShareLink(item);
});
this.setState({
loading: false,
hasMore: res.data.length == PER_PAGE,
items: this._sortItems(items, this.state.sortBy, this.state.sortOrder)
});
}).catch((error) => {
@@ -453,6 +466,40 @@ class ShareAdminShareLinks extends Component {
});
}
handleScroll = (event) => {
if (!this.state.isLoadingMore && this.state.hasMore) {
const clientHeight = event.target.clientHeight;
const scrollHeight = event.target.scrollHeight;
const scrollTop = event.target.scrollTop;
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (isBottom) { // scroll to the bottom
this.setState({isLoadingMore: true}, () => {
this.getMore();
});
}
}
};
getMore = () => {
const { page } = this.state;
seafileAPI.listShareLinks({ page: page + 1 }).then((res) => {
let moreItems = res.data.map(item => {
return new ShareLink(item);
});
this.setState({
isLoadingMore: false,
hasMore: res.data.length == PER_PAGE,
page: page + 1,
items: this._sortItems(this.state.items.concat(moreItems), this.state.sortBy, this.state.sortOrder)
});
}).catch((error) => {
this.setState({
isLoadingMore: false,
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
});
};
onRemoveLink = (item) => {
seafileAPI.deleteShareLink(item.token).then(() => {
let items = this.state.items.filter(uploadItem => {
@@ -511,9 +558,10 @@ class ShareAdminShareLinks extends Component {
</ul>
{(!Utils.isDesktop() && this.state.items.length > 0) && <span className="sf3-font sf3-font-sort action-icon" onClick={this.toggleSortOptionsDialog}></span>}
</div>
<div className="cur-view-content">
<div className="cur-view-content" onScroll={this.handleScroll}>
<Content
loading={this.state.loading}
isLoadingMore={this.state.isLoadingMore}
errorMsg={this.state.errorMsg}
items={this.state.items}
sortBy={this.state.sortBy}