1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 01:44:13 +00:00

Merge branch '7.1' into master

This commit is contained in:
lian
2020-08-19 14:01:17 +08:00
107 changed files with 13230 additions and 14827 deletions

View File

@@ -40,7 +40,8 @@ class GroupView extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
isLoading: true, // first loading
isLoadingMore: false,
errMessage: '',
emptyTip: null,
currentGroup: null,
@@ -51,6 +52,9 @@ class GroupView extends React.Component {
sortOrder: cookie.load('seafile-repo-dir-sort-order') || 'asc', // 'asc' or 'desc'
isSortOptionsDialogOpen: false,
repoList: [],
currentPage: 1,
perPage: 50,
hasNextPage: false,
libraryType: 'group',
isCreateRepoDialogShow: false,
isDepartmentGroup: false,
@@ -91,8 +95,9 @@ class GroupView extends React.Component {
isStaff: isStaff,
isDepartmentGroup: isDepartmentGroup,
isOwner: isOwner,
repoList: [] // empty it for the current group
});
this.loadRepos(groupID);
this.loadRepos(this.state.currentPage);
}).catch((error) => {
this.setState({
isLoading: false,
@@ -101,20 +106,32 @@ class GroupView extends React.Component {
});
}
loadRepos = (groupID) => {
this.setState({isLoading: true});
seafileAPI.listGroupRepos(groupID).then((res) => {
let repoList = res.data.map(item => {
loadRepos = (page) => {
const { perPage } = this.state;
seafileAPI.listGroupRepos(this.props.groupID, page, perPage).then((res) => {
let hasNextPage = true;
if (res.data.length < perPage) {
hasNextPage = false;
}
let repoList = this.state.repoList;
let newRepoList = res.data.map(item => {
let repo = new Repo(item);
return repo;
});
if (newRepoList.length) {
repoList = repoList.concat(newRepoList);
}
this.setState({
isLoading: false,
isLoadingMore: false,
currentPage: page,
hasNextPage: hasNextPage,
repoList: Utils.sortRepos(repoList, this.state.sortBy, this.state.sortOrder)
});
}).catch((error) => {
this.setState({
isLoading: false,
isLoadingMore: false,
errMessage: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
});
@@ -191,23 +208,11 @@ class GroupView extends React.Component {
onItemDelete = (repo) => {
let groupID = this.props.groupID;
seafileAPI.deleteGroupOwnedLibrary(groupID, repo.repo_id).then(() => {
let repoList = this.state.repoList.filter(item => {
return item.repo_id !== repo.repo_id;
});
this.setState({repoList: repoList});
this.loadGroup(groupID);
let name = repo.repo_name;
var msg = gettext('Successfully deleted {name}.').replace('{name}', name);
toaster.success(msg);
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
let name = repo.repo_name;
errMessage = gettext('Failed to delete {name}.').replace('{name}', name);
}
toaster.danger(errMessage);
let repoList = this.state.repoList.filter(item => {
return item.repo_id !== repo.repo_id;
});
this.setState({repoList: repoList});
this.loadGroup(groupID);
}
addRepoItem = (repo) => {
@@ -359,6 +364,22 @@ class GroupView extends React.Component {
});
}
handleScroll = (event) => {
// isLoadingMore: to avoid repeated request
const { currentPage, hasNextPage, isLoadingMore } = this.state;
if (hasNextPage && !isLoadingMore) {
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.loadRepos(currentPage + 1);
});
}
}
}
render() {
let { errMessage, emptyTip, currentGroup, isDepartmentGroup, isStaff } = this.state;
let isShowSettingIcon = false;
@@ -504,13 +525,14 @@ class GroupView extends React.Component {
</Fragment>
)}
</div>
<div className="cur-view-content">
<div className="cur-view-content d-block" onScroll={this.handleScroll}>
{this.state.isLoading && <Loading />}
{(!this.state.isLoading && errMessage) && <div className="error text-center mt-2">{errMessage}</div>}
{(!this.state.isLoading && this.state.repoList.length === 0) && emptyTip}
{(!this.state.isLoading && this.state.repoList.length > 0) &&
<SharedRepoListView
repoList={this.state.repoList}
hasNextPage={this.state.hasNextPage}
currentGroup={this.state.currentGroup}
sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder}

View File

@@ -53,23 +53,10 @@ class RepoListViewPanel extends React.Component {
}
onItemDelete = (repo) => {
let group = this.props.group;
seafileAPI.deleteGroupOwnedLibrary(group.id, repo.repo_id).then(() => {
let repoList = this.state.repoList.filter(item => {
return item.repo_id !== repo.repo_id;
});
this.setState({repoList: repoList});
let name = repo.repo_name;
var msg = gettext('Successfully deleted {name}.').replace('{name}', name);
toaster.success(msg);
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
let name = repo.repo_name;
errMessage = gettext('Failed to delete {name}.').replace('{name}', name);
}
toaster.danger(errMessage);
let repoList = this.state.repoList.filter(item => {
return item.repo_id !== repo.repo_id;
});
this.setState({repoList: repoList});
}
onItemRename = (repo, newName) => {

View File

@@ -49,7 +49,8 @@ class MylibRepoListItem extends React.Component {
isLabelRepoStateDialogOpen: false,
isFolderPermissionDialogShow: false,
isAPITokenDialogShow: false,
isRepoShareUploadLinksDialogOpen: false
isRepoShareUploadLinksDialogOpen: false,
isRepoDeleted: false,
};
}
@@ -232,6 +233,12 @@ class MylibRepoListItem extends React.Component {
onDeleteRepo = (repo) => {
seafileAPI.deleteRepo(repo.repo_id).then((res) => {
this.setState({
isRepoDeleted: true,
isDeleteDialogShow: false,
});
this.props.onDeleteRepo(repo);
let name = repo.repo_name;
var msg = gettext('Successfully deleted {name}.').replace('{name}', name);
@@ -243,6 +250,8 @@ class MylibRepoListItem extends React.Component {
errMessage = gettext('Failed to delete {name}.').replace('{name}', name);
}
toaster.danger(errMessage);
this.setState({isRepoDeleted: false});
});
}
@@ -364,6 +373,7 @@ class MylibRepoListItem extends React.Component {
<ModalPortal>
<DeleteRepoDialog
repo={repo}
isRepoDeleted={this.state.isRepoDeleted}
onDeleteRepo={this.onDeleteRepo}
toggle={this.onDeleteToggle}
/>

View File

@@ -103,7 +103,8 @@ class Item extends Component {
this.state = {
isOpIconShown: false,
deleted: false,
isDeleteRepoDialogOpen: false
isDeleteRepoDialogOpen: false,
isRepoDeleted: false,
};
}
@@ -134,13 +135,16 @@ class Item extends Component {
const repo = this.props.data;
seafileAPI.orgAdminDeleteOrgRepo(orgID, repo.repo_id).then((res) => {
this.setState({
deleted: true
deleted: true,
isRepoDeleted: true,
});
const msg = gettext('Successfully deleted {name}.').replace('{name}', repo.name);
toaster.success(msg);
}).catch((error) => {
const errorMsg = Utils.getErrorMsg(error);
toaster.danger(errorMsg);
this.setState({isRepoDeleted: false});
});
}
@@ -165,13 +169,14 @@ class Item extends Component {
<a href="#" className={`action-icon sf2-icon-delete${isOpIconShown ? '' : ' invisible'}`} title={gettext('Delete')} onClick={this.handleDeleteIconClick}></a>
</td>
</tr>
{isDeleteRepoDialogOpen &&
<DeleteRepoDialog
repo={repo}
onDeleteRepo={this.deleteRepo}
toggle={this.toggleDeleteRepoDialog}
/>
}
{isDeleteRepoDialogOpen && (
<DeleteRepoDialog
repo={repo}
isRepoDeleted={this.state.isRepoDeleted}
onDeleteRepo={this.deleteRepo}
toggle={this.toggleDeleteRepoDialog}
/>
)}
</Fragment>
);
}

View File

@@ -103,7 +103,8 @@ class Item extends Component {
this.state = {
isOpIconShown: false,
deleted: false,
isDeleteRepoDialogOpen: false
isDeleteRepoDialogOpen: false,
isRepoDeleted: false,
};
}
@@ -134,13 +135,16 @@ class Item extends Component {
const repo = this.props.data;
seafileAPI.orgAdminDeleteOrgRepo(orgID, repo.repo_id).then((res) => {
this.setState({
deleted: true
deleted: true,
isRepoDeleted: true,
});
const msg = gettext('Successfully deleted {name}.').replace('{name}', repo.repo_name);
toaster.success(msg);
}).catch((error) => {
const errorMsg = Utils.getErrorMsg(error);
toaster.danger(errorMsg);
this.setState({isRepoDeleted: false});
});
}
@@ -165,13 +169,14 @@ class Item extends Component {
<a href="#" className={`action-icon sf2-icon-delete${isOpIconShown ? '' : ' invisible'}`} title={gettext('Delete')} onClick={this.handleDeleteIconClick}></a>
</td>
</tr>
{isDeleteRepoDialogOpen &&
<DeleteRepoDialog
repo={repo}
onDeleteRepo={this.deleteRepo}
toggle={this.toggleDeleteRepoDialog}
/>
}
{isDeleteRepoDialogOpen && (
<DeleteRepoDialog
repo={repo}
isRepoDeleted={this.state.isRepoDeleted}
onDeleteRepo={this.deleteRepo}
toggle={this.toggleDeleteRepoDialog}
/>
)}
</Fragment>
);
}

View File

@@ -130,20 +130,26 @@ class Item extends Component {
isShareDialogOpen: false,
isDeleteDialogOpen: false,
isTransferDialogOpen: false,
isHistorySettingDialogOpen: false
isHistorySettingDialogOpen: false,
isRepoDeleted: false,
};
}
onDeleteRepo = (repo) => {
seafileAPI.sysAdminDeleteRepo(repo.id).then((res) => {
this.props.onDeleteRepo(repo);
this.setState({
isDeleteDialogOpen: false,
isRepoDeleted: true,
});
const msg = gettext('Successfully deleted {name}.').replace('{name}', repo.name);
toaster.success(msg);
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
this.setState({isRepoDeleted: false});
});
this.toggleDeleteDialog();
}
onTransferRepo = (owner) => {
@@ -325,6 +331,7 @@ class Item extends Component {
<ModalPortal>
<DeleteRepoDialog
repo={repo}
isRepoDeleted={this.state.isRepoDeleted}
onDeleteRepo={this.onDeleteRepo}
toggle={this.toggleDeleteDialog}
/>