mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-23 04:18:21 +00:00
Watch unwatch (#7927)
* ['library view' page] added 'Watch/Unwatch File Changes' to the 'Others' section * ['Library view', 'My Libraries'] removed the 'Watch/Unwatch File Changes' in the 'Others - More' menu of 'Library view' page; for the library items in 'My Libraries', removed the 'Watch/Unwatch File Changes' operation options from the menus, and removed the 'being watched' icon and the tooltip. * ['Shared with me' page] for desktop & mobile: removed the 'Watch/Unwatch File Changes' options from the operation menus, and removed the 'being watched' icon and the tooltip. * ['Group', 'Department' library list] for desktop & mobile: removed the 'Watch/Unwatch File Changes' options from the operation menus, and removed the 'being watched' icon and the tooltip.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext, username } from '../../../utils/constants';
|
||||
import { gettext, username, isPro } from '../../../utils/constants';
|
||||
import { Utils } from '../../../utils/utils';
|
||||
import TreeSection from '../../tree-section';
|
||||
import TrashDialog from '../../dialog/trash-dialog';
|
||||
@@ -10,11 +10,12 @@ import { eventBus } from '../../common/event-bus';
|
||||
import { EVENT_BUS_TYPE } from '../../common/event-bus-type';
|
||||
import { TAB } from '../../../constants/repo-setting-tabs';
|
||||
import LibraryMoreOperations from './library-more-operations';
|
||||
import WatchUnwatchFileChanges from './watch-unwatch-file-changes';
|
||||
|
||||
import './index.css';
|
||||
|
||||
const DirOthers = ({ userPerm, repoID, currentRepoInfo, updateRepoInfo }) => {
|
||||
const { owner_email, is_admin, repo_name: repoName } = currentRepoInfo;
|
||||
const { owner_email, is_admin, repo_name: repoName, permission } = currentRepoInfo;
|
||||
|
||||
const showSettings = is_admin; // repo owner, department admin, shared with 'Admin' permission
|
||||
let [isSettingsDialogOpen, setSettingsDialogOpen] = useState(false);
|
||||
@@ -55,8 +56,16 @@ const DirOthers = ({ userPerm, repoID, currentRepoInfo, updateRepoInfo }) => {
|
||||
const isDesktop = Utils.isDesktop();
|
||||
const isRepoOwner = owner_email == username;
|
||||
|
||||
const enableMonitorRepo = isPro && (permission == 'r' || permission == 'rw');
|
||||
|
||||
return (
|
||||
<TreeSection title={gettext('Others')} className="dir-others">
|
||||
{enableMonitorRepo && (
|
||||
<WatchUnwatchFileChanges
|
||||
repo={currentRepoInfo}
|
||||
updateRepoInfo={updateRepoInfo}
|
||||
/>
|
||||
)}
|
||||
{showSettings && (
|
||||
<div className='dir-others-item text-nowrap' title={gettext('Settings')} onClick={toggleSettingsDialog}>
|
||||
<span className="sf3-font-set-up sf3-font"></span>
|
||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { navigate } from '@gatsbyjs/reach-router';
|
||||
import { Utils } from '../../../utils/utils';
|
||||
import { seafileAPI } from '../../../utils/seafile-api';
|
||||
import { userAPI } from '../../../utils/user-api';
|
||||
import { gettext, siteRoot } from '../../../utils/constants';
|
||||
import ModalPortal from '../../../components/modal-portal';
|
||||
import toaster from '../../../components/toast';
|
||||
@@ -15,7 +16,6 @@ import LibSubFolderPermissionDialog from '../../../components/dialog/lib-sub-fol
|
||||
import RepoAPITokenDialog from '../../../components/dialog/repo-api-token-dialog';
|
||||
import RepoShareAdminDialog from '../../../components/dialog/repo-share-admin-dialog';
|
||||
import OfficeSuiteDialog from '../../../components/dialog/repo-office-suite-dialog';
|
||||
import { userAPI } from '../../../utils/user-api';
|
||||
import MylibRepoMenu from '../../../pages/my-libs/mylib-repo-menu';
|
||||
|
||||
const propTypes = {
|
||||
@@ -80,30 +80,6 @@ class LibraryMoreOperations extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
watchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.monitorRepo(repo.repo_id).then(() => {
|
||||
this.props.updateRepoInfo({ 'monitored': true });
|
||||
const message = gettext('Successfully watched the library.');
|
||||
toaster.success(message);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
unwatchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.unMonitorRepo(repo.repo_id).then(() => {
|
||||
this.props.updateRepoInfo({ 'monitored': false });
|
||||
const message = gettext('Successfully unwatched the library.');
|
||||
toaster.success(message);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
onRenameToggle = () => {
|
||||
this.setState({ isRenameRepoDialogOpen: !this.state.isRenameRepoDialogOpen });
|
||||
};
|
||||
|
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Utils } from '../../../utils/utils';
|
||||
import { seafileAPI } from '../../../utils/seafile-api';
|
||||
import { gettext } from '../../../utils/constants';
|
||||
import toaster from '../../../components/toast';
|
||||
|
||||
const propTypes = {
|
||||
repo: PropTypes.object.isRequired,
|
||||
updateRepoInfo: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class WatchUnwatchFileChanges extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
};
|
||||
}
|
||||
|
||||
watchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.monitorRepo(repo.repo_id).then(() => {
|
||||
this.props.updateRepoInfo({ 'monitored': true });
|
||||
const message = gettext('Successfully watched the library.');
|
||||
toaster.success(message);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
unwatchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.unMonitorRepo(repo.repo_id).then(() => {
|
||||
this.props.updateRepoInfo({ 'monitored': false });
|
||||
const message = gettext('Successfully unwatched the library.');
|
||||
toaster.success(message);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { repo } = this.props;
|
||||
const { monitored } = repo;
|
||||
|
||||
const monitorText = monitored ? gettext('Unwatch File Changes') : gettext('Watch File Changes');
|
||||
const clickHandler = monitored ? this.unwatchFileChanges : this.watchFileChanges;
|
||||
|
||||
return (
|
||||
<div className='dir-others-item text-nowrap' title={monitorText} onClick={clickHandler}>
|
||||
<span className="sf3-font-monitor sf3-font"></span>
|
||||
<span className="dir-others-item-text">{monitorText}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WatchUnwatchFileChanges.propTypes = propTypes;
|
||||
|
||||
export default WatchUnwatchFileChanges;
|
@@ -1,31 +0,0 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { UncontrolledTooltip } from 'reactstrap';
|
||||
import { gettext } from '../utils/constants';
|
||||
|
||||
const propTypes = {
|
||||
repoID: PropTypes.string.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
class RepoMonitoredIcon extends React.Component {
|
||||
|
||||
render() {
|
||||
const { repoID, className } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
<i id={`watching-${repoID}`} className={`sf3-font-monitor sf3-font ${className ? className : ''}`}></i>
|
||||
<UncontrolledTooltip
|
||||
placement="bottom"
|
||||
target={`#watching-${repoID}`}
|
||||
>
|
||||
{gettext('You are watching file changes of this library.')}
|
||||
</UncontrolledTooltip>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RepoMonitoredIcon.propTypes = propTypes;
|
||||
|
||||
export default RepoMonitoredIcon;
|
@@ -19,7 +19,6 @@ import { userAPI } from '../../utils/user-api';
|
||||
import toaster from '../toast';
|
||||
import RepoAPITokenDialog from '../dialog/repo-api-token-dialog';
|
||||
import RepoShareAdminDialog from '../dialog/repo-share-admin-dialog';
|
||||
import RepoMonitoredIcon from '../../components/repo-monitored-icon';
|
||||
import { LIST_MODE } from '../dir-view-mode/constants';
|
||||
import TransferDialog from '../dialog/transfer-dialog';
|
||||
|
||||
@@ -36,7 +35,6 @@ const propTypes = {
|
||||
onItemUnshare: PropTypes.func.isRequired,
|
||||
onItemRename: PropTypes.func,
|
||||
onItemDelete: PropTypes.func,
|
||||
onMonitorRepo: PropTypes.func,
|
||||
onContextMenu: PropTypes.func.isRequired,
|
||||
onTransferRepo: PropTypes.func
|
||||
};
|
||||
@@ -189,36 +187,10 @@ class SharedRepoListItem extends React.Component {
|
||||
case 'Reset Password':
|
||||
this.onResetPasswordToggle();
|
||||
break;
|
||||
case 'Watch File Changes':
|
||||
this.watchFileChanges();
|
||||
break;
|
||||
case 'Unwatch File Changes':
|
||||
this.unwatchFileChanges();
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
};
|
||||
|
||||
watchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.monitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, true);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
unwatchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.unMonitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, false);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
onItemRenameToggle = () => {
|
||||
this.props.onFreezedItem();
|
||||
this.setState({
|
||||
@@ -402,14 +374,10 @@ class SharedRepoListItem extends React.Component {
|
||||
if (repo.encrypted && enableResetEncryptedRepoPassword && isEmailConfigured) {
|
||||
operations.push('Reset Password');
|
||||
}
|
||||
if (repo.permission == 'r' || repo.permission == 'rw') {
|
||||
const monitorOp = repo.monitored ? 'Unwatch File Changes' : 'Watch File Changes';
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
if (Utils.isDesktop()) {
|
||||
operations.push('Divider', 'Advanced');
|
||||
}
|
||||
return operations;
|
||||
return operations.filter((op, i, arr) => !(op === 'Divider' && arr[i + 1] === 'Divider'));
|
||||
} else {
|
||||
operations.push('Unshare');
|
||||
}
|
||||
@@ -422,10 +390,6 @@ class SharedRepoListItem extends React.Component {
|
||||
operations.push('Unshare');
|
||||
}
|
||||
}
|
||||
if (repo.permission == 'r' || repo.permission == 'rw') {
|
||||
const monitorOp = repo.monitored ? 'Unwatch File Changes' : 'Watch File Changes';
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
} else {
|
||||
if (isRepoOwner) {
|
||||
operations.push('Share');
|
||||
@@ -548,32 +512,6 @@ class SharedRepoListItem extends React.Component {
|
||||
return <Fragment key={item}>{shareOperation}</Fragment>;
|
||||
case 'Unshare':
|
||||
return <Fragment key={item}>{unshareOperation}</Fragment>;
|
||||
case 'Watch File Changes':
|
||||
case 'Unwatch File Changes':
|
||||
return (
|
||||
<Dropdown isOpen={this.state.isItemMenuShow} toggle={this.toggleOperationMenu} key={item}>
|
||||
<DropdownToggle
|
||||
tag="i"
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
className="op-icon sf3-font-more sf3-font"
|
||||
title={gettext('More operations')}
|
||||
aria-label={gettext('More operations')}
|
||||
data-toggle="dropdown"
|
||||
aria-expanded={this.state.isItemMenuShow}
|
||||
aria-haspopup={true}
|
||||
style={{ 'minWidth': '0' }}
|
||||
onClick={this.clickOperationMenuToggle}
|
||||
onKeyDown={this.onDropdownToggleKeyDown}
|
||||
/>
|
||||
<DropdownMenu>
|
||||
{[item].map((item, index) => {
|
||||
return <DropdownItem key={index} data-toggle={item} onClick={this.onMenuItemClick} onKeyDown={this.onMenuItemKeyDown}>{this.translateMenuItem(item)}</DropdownItem>;
|
||||
})}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
);
|
||||
// no default
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -642,7 +580,6 @@ class SharedRepoListItem extends React.Component {
|
||||
<Rename name={repo.repo_name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel}/> :
|
||||
<Fragment>
|
||||
<Link to={libPath}>{repo.repo_name}</Link>
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="ml-1 op-icon" />}
|
||||
</Fragment>
|
||||
}
|
||||
</td>
|
||||
@@ -675,7 +612,6 @@ class SharedRepoListItem extends React.Component {
|
||||
>
|
||||
</i>
|
||||
}
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="op-icon library-grid-item-icon" />}
|
||||
</Fragment>
|
||||
}
|
||||
</div>
|
||||
@@ -703,10 +639,7 @@ class SharedRepoListItem extends React.Component {
|
||||
<td onClick={this.visitRepo}>
|
||||
{this.state.isRenaming ?
|
||||
<Rename name={repo.repo_name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel} /> :
|
||||
<Fragment>
|
||||
<Link to={libPath}>{repo.repo_name}</Link>
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="ml-1 op-icon" />}
|
||||
</Fragment>
|
||||
<Link to={libPath}>{repo.repo_name}</Link>
|
||||
}
|
||||
<br />
|
||||
<span className="item-meta-info" title={repo.owner_contact_email}>{repo.owner_name}</span>
|
||||
|
@@ -24,7 +24,6 @@ const propTypes = {
|
||||
onItemDelete: PropTypes.func,
|
||||
onItemRename: PropTypes.func,
|
||||
hasNextPage: PropTypes.bool,
|
||||
onMonitorRepo: PropTypes.func,
|
||||
inAllLibs: PropTypes.bool,
|
||||
onTransferRepo: PropTypes.func,
|
||||
};
|
||||
@@ -136,7 +135,6 @@ class SharedRepoListView extends React.Component {
|
||||
onItemUnshare={this.props.onItemUnshare}
|
||||
onItemDelete={this.props.onItemDelete}
|
||||
onItemRename={this.props.onItemRename}
|
||||
onMonitorRepo={this.props.onMonitorRepo}
|
||||
currentViewMode={currentViewMode}
|
||||
onContextMenu={this.onContextMenu}
|
||||
/>
|
||||
|
@@ -12,7 +12,6 @@ const propTypes = {
|
||||
inAllLibs: PropTypes.bool,
|
||||
currentViewMode: PropTypes.string,
|
||||
group: PropTypes.object.isRequired,
|
||||
onMonitorRepo: PropTypes.func,
|
||||
renameRelatedGroupsRepos: PropTypes.func,
|
||||
deleteRelatedGroupsRepos: PropTypes.func,
|
||||
addRepoToGroup: PropTypes.func,
|
||||
@@ -52,10 +51,6 @@ class GroupItem extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
onMonitorRepo = (repo, monitored) => {
|
||||
this.props.onMonitorRepo(repo, monitored);
|
||||
};
|
||||
|
||||
addNewRepo = (newRepo) => {
|
||||
const { group } = this.props;
|
||||
const { id: group_id } = group;
|
||||
@@ -109,7 +104,6 @@ class GroupItem extends React.Component {
|
||||
onItemUnshare={this.onItemUnshare}
|
||||
onItemDelete={this.onItemDelete}
|
||||
onItemRename={this.onItemRename}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
onTransferRepo={this.props.onTransferRepo}
|
||||
currentViewMode={currentViewMode}
|
||||
/>
|
||||
|
@@ -178,16 +178,6 @@ class GroupView extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
onMonitorRepo = (repo, monitored) => {
|
||||
let repoList = this.state.repoList.map(item => {
|
||||
if (item.repo_id === repo.repo_id) {
|
||||
item.monitored = monitored;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
this.setState({ repoList: repoList });
|
||||
};
|
||||
|
||||
sortItems = (sortBy, sortOrder) => {
|
||||
cookie.save('seafile-repo-dir-sort-by', sortBy);
|
||||
cookie.save('seafile-repo-dir-sort-order', sortOrder);
|
||||
@@ -335,28 +325,32 @@ class GroupView extends React.Component {
|
||||
className={classnames('cur-view-content', 'd-block', 'repos-container', { 'pt-3': currentViewMode != LIST_MODE })}
|
||||
onScroll={this.handleScroll}
|
||||
>
|
||||
{isLoading ? <Loading /> : errMessage ?
|
||||
<div className="w-100 h-100 d-flex flex-column align-items-center justify-content-center text-center">
|
||||
<img src={`${mediaUrl}img/error-tip.png`} alt="" width="100" />
|
||||
<p className="mt-2">{errMessage}</p>
|
||||
</div>
|
||||
: repoList.length == 0
|
||||
? emptyTip
|
||||
:
|
||||
<SharedRepoListView
|
||||
repoList={this.state.repoList}
|
||||
hasNextPage={this.state.hasNextPage}
|
||||
currentGroup={this.state.currentGroup}
|
||||
sortBy={this.state.sortBy}
|
||||
sortOrder={this.state.sortOrder}
|
||||
sortItems={this.sortItems}
|
||||
onItemUnshare={this.onItemUnshare}
|
||||
onItemDelete={this.onItemDelete}
|
||||
onItemRename={this.onItemRename}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
onTransferRepo={this.onItemTransfer}
|
||||
currentViewMode={currentViewMode}
|
||||
/>
|
||||
{isLoading
|
||||
? <Loading />
|
||||
: errMessage
|
||||
? (
|
||||
<div className="w-100 h-100 d-flex flex-column align-items-center justify-content-center text-center">
|
||||
<img src={`${mediaUrl}img/error-tip.png`} alt="" width="100" />
|
||||
<p className="mt-2">{errMessage}</p>
|
||||
</div>
|
||||
)
|
||||
: repoList.length == 0
|
||||
? emptyTip
|
||||
: (
|
||||
<SharedRepoListView
|
||||
repoList={this.state.repoList}
|
||||
hasNextPage={this.state.hasNextPage}
|
||||
currentGroup={this.state.currentGroup}
|
||||
sortBy={this.state.sortBy}
|
||||
sortOrder={this.state.sortOrder}
|
||||
sortItems={this.sortItems}
|
||||
onItemUnshare={this.onItemUnshare}
|
||||
onItemDelete={this.onItemDelete}
|
||||
onItemRename={this.onItemRename}
|
||||
onTransferRepo={this.onItemTransfer}
|
||||
currentViewMode={currentViewMode}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -230,25 +230,6 @@ class Libraries extends Component {
|
||||
this.setState({ repoList });
|
||||
};
|
||||
|
||||
monitorRepo = (repoId, monitored, repoList) => {
|
||||
if (!Array.isArray(repoList) || repoList.length === 0) {
|
||||
return repoList;
|
||||
}
|
||||
return repoList.map((repo) => {
|
||||
if (repo.repo_id === repoId) {
|
||||
return { ...repo, monitored };
|
||||
}
|
||||
return repo;
|
||||
});
|
||||
};
|
||||
|
||||
onMonitorRepo = (repo, monitored) => {
|
||||
const targetRepoId = repo.repo_id;
|
||||
const repoList = this.monitorRepo(targetRepoId, monitored, this.state.repoList);
|
||||
this.monitorRelatedGroupsRepos(targetRepoId, monitored);
|
||||
this.setState({ repoList });
|
||||
};
|
||||
|
||||
deleteRepo = (repoId, repoList) => {
|
||||
if (!Array.isArray(repoList) || repoList.length === 0) {
|
||||
return repoList;
|
||||
@@ -360,24 +341,6 @@ class Libraries extends Component {
|
||||
this.setState({ groupList: updatedGroups });
|
||||
};
|
||||
|
||||
monitorRelatedGroupsRepos = (repoId, monitored) => {
|
||||
const relatedGroups = this.groupsReposManager.getRepoInGroupsIdsById(repoId);
|
||||
if (relatedGroups.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { groupList } = this.state;
|
||||
const updatedGroups = groupList.map((group) => {
|
||||
const { repos } = group;
|
||||
if (!relatedGroups.includes(group.id)) {
|
||||
return group;
|
||||
}
|
||||
const updatedRepos = this.monitorRepo(repoId, monitored, repos);
|
||||
return { ...group, repos: updatedRepos };
|
||||
});
|
||||
this.setState({ groupList: updatedGroups });
|
||||
};
|
||||
|
||||
deleteRelatedGroupsRepos = (repoId) => {
|
||||
const relatedGroups = this.groupsReposManager.getRepoInGroupsIdsById(repoId);
|
||||
if (relatedGroups.length === 0) {
|
||||
@@ -486,7 +449,6 @@ class Libraries extends Component {
|
||||
onRenameRepo={this.onRenameRepo}
|
||||
onDeleteRepo={this.onDeleteRepo}
|
||||
onTransferRepo={this.onTransferRepo}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
onRepoClick={this.onRepoClick}
|
||||
sortRepoList={this.sortRepoList}
|
||||
inAllLibs={true}
|
||||
@@ -521,7 +483,6 @@ class Libraries extends Component {
|
||||
key={group.id}
|
||||
inAllLibs={true}
|
||||
group={group}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
renameRelatedGroupsRepos={this.renameRelatedGroupsRepos}
|
||||
deleteRelatedGroupsRepos={this.deleteRelatedGroupsRepos}
|
||||
addRepoToGroup={this.addRepoToGroup}
|
||||
|
@@ -113,16 +113,6 @@ class MyLibraries extends Component {
|
||||
this.setState({ repoList: repoList });
|
||||
};
|
||||
|
||||
onMonitorRepo = (repo, monitored) => {
|
||||
let repoList = this.state.repoList.map(item => {
|
||||
if (item.repo_id === repo.repo_id) {
|
||||
item.monitored = monitored;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
this.setState({ repoList: repoList });
|
||||
};
|
||||
|
||||
onDeleteRepo = (repo) => {
|
||||
let repoList = this.state.repoList.filter(item => {
|
||||
return item.repo_id !== repo.repo_id;
|
||||
@@ -203,7 +193,6 @@ class MyLibraries extends Component {
|
||||
onRenameRepo={this.onRenameRepo}
|
||||
onDeleteRepo={this.onDeleteRepo}
|
||||
onTransferRepo={this.onTransferRepo}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
sortRepoList={this.sortRepoList}
|
||||
currentViewMode={currentViewMode}
|
||||
/>
|
||||
|
@@ -21,7 +21,6 @@ import MylibRepoMenu from './mylib-repo-menu';
|
||||
import RepoAPITokenDialog from '../../components/dialog/repo-api-token-dialog';
|
||||
import RepoShareAdminDialog from '../../components/dialog/repo-share-admin-dialog';
|
||||
import OfficeSuiteDialog from '../../components/dialog/repo-office-suite-dialog';
|
||||
import RepoMonitoredIcon from '../../components/repo-monitored-icon';
|
||||
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
||||
import { userAPI } from '../../utils/user-api';
|
||||
|
||||
@@ -35,7 +34,6 @@ const propTypes = {
|
||||
onRenameRepo: PropTypes.func.isRequired,
|
||||
onDeleteRepo: PropTypes.func.isRequired,
|
||||
onTransferRepo: PropTypes.func.isRequired,
|
||||
onMonitorRepo: PropTypes.func.isRequired,
|
||||
onContextMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
@@ -113,12 +111,6 @@ class MylibRepoListItem extends React.Component {
|
||||
case 'Reset Password':
|
||||
this.onResetPasswordToggle();
|
||||
break;
|
||||
case 'Watch File Changes':
|
||||
this.watchFileChanges();
|
||||
break;
|
||||
case 'Unwatch File Changes':
|
||||
this.unwatchFileChanges();
|
||||
break;
|
||||
case 'Folder Permission':
|
||||
this.onFolderPermissionToggle();
|
||||
break;
|
||||
@@ -170,26 +162,6 @@ class MylibRepoListItem extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
watchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.monitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, true);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
unwatchFileChanges = () => {
|
||||
const { repo } = this.props;
|
||||
seafileAPI.unMonitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, false);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
onShareToggle = () => {
|
||||
this.setState({ isShareDialogShow: !this.state.isShareDialogShow });
|
||||
};
|
||||
@@ -333,7 +305,6 @@ class MylibRepoListItem extends React.Component {
|
||||
{!this.state.isRenaming && repo.repo_name && (
|
||||
<Fragment>
|
||||
<Link to={repoURL}>{repo.repo_name}</Link>
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="ml-1 op-icon" />}
|
||||
</Fragment>
|
||||
)}
|
||||
{!this.state.isRenaming && !repo.repo_name &&
|
||||
@@ -389,7 +360,6 @@ class MylibRepoListItem extends React.Component {
|
||||
>
|
||||
</i>
|
||||
}
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="op-icon library-grid-item-icon" />}
|
||||
</Fragment>
|
||||
)}
|
||||
{!this.state.isRenaming && !repo.repo_name &&
|
||||
@@ -433,7 +403,6 @@ class MylibRepoListItem extends React.Component {
|
||||
{!this.state.isRenaming && repo.repo_name && (
|
||||
<div>
|
||||
<Link to={repoURL}>{repo.repo_name}</Link>
|
||||
{repo.monitored && <RepoMonitoredIcon repoID={repo.repo_id} className="ml-1 op-icon" />}
|
||||
</div>
|
||||
)}
|
||||
{!this.state.isRenaming && !repo.repo_name &&
|
||||
|
@@ -18,7 +18,6 @@ const propTypes = {
|
||||
onRenameRepo: PropTypes.func.isRequired,
|
||||
onDeleteRepo: PropTypes.func.isRequired,
|
||||
onTransferRepo: PropTypes.func.isRequired,
|
||||
onMonitorRepo: PropTypes.func.isRequired,
|
||||
inAllLibs: PropTypes.bool, // for 'My Libraries' in 'Files' page
|
||||
currentViewMode: PropTypes.string,
|
||||
};
|
||||
@@ -101,7 +100,6 @@ class MylibRepoListView extends React.Component {
|
||||
onRenameRepo={this.props.onRenameRepo}
|
||||
onDeleteRepo={this.props.onDeleteRepo}
|
||||
onTransferRepo={this.props.onTransferRepo}
|
||||
onMonitorRepo={this.props.onMonitorRepo}
|
||||
currentViewMode={this.props.currentViewMode}
|
||||
onContextMenu={this.onContextMenu}
|
||||
inAllLibs={this.props.inAllLibs}
|
||||
|
@@ -105,11 +105,6 @@ class MylibRepoMenu extends React.Component {
|
||||
operations.push('Reset Password');
|
||||
}
|
||||
|
||||
if (isPro) {
|
||||
const monitorOp = repo.monitored ? 'Unwatch File Changes' : 'Watch File Changes';
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
|
||||
operations.push('Divider', 'Advanced');
|
||||
// Remove adjacent excess 'Divider'
|
||||
for (let i = 0; i < operations.length; i++) {
|
||||
@@ -160,12 +155,6 @@ class MylibRepoMenu extends React.Component {
|
||||
case 'Reset Password':
|
||||
translateResult = gettext('Reset Password');
|
||||
break;
|
||||
case 'Watch File Changes':
|
||||
translateResult = gettext('Watch File Changes');
|
||||
break;
|
||||
case 'Unwatch File Changes':
|
||||
translateResult = gettext('Unwatch File Changes');
|
||||
break;
|
||||
case 'Folder Permission':
|
||||
translateResult = gettext('Folder Permission');
|
||||
break;
|
||||
|
@@ -105,7 +105,6 @@ class Content extends Component {
|
||||
isDesktop={isDesktop}
|
||||
isItemFreezed={this.state.isItemFreezed}
|
||||
freezeItem={this.freezeItem}
|
||||
onMonitorRepo={this.props.onMonitorRepo}
|
||||
currentViewMode={currentViewMode}
|
||||
onContextMenu={this.onContextMenu}
|
||||
/>;
|
||||
@@ -171,7 +170,6 @@ Content.propTypes = {
|
||||
sortBy: PropTypes.string.isRequired,
|
||||
sortOrder: PropTypes.string.isRequired,
|
||||
sortItems: PropTypes.func.isRequired,
|
||||
onMonitorRepo: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default Content;
|
||||
|
@@ -66,16 +66,6 @@ class SharedLibraries extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
onMonitorRepo = (repo, monitored) => {
|
||||
let items = this.state.items.map(item => {
|
||||
if (item.repo_id === repo.repo_id) {
|
||||
item.monitored = monitored;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
this.setState({ items: items });
|
||||
};
|
||||
|
||||
renderContent = (currentViewMode) => {
|
||||
const { inAllLibs = false, repoList } = this.props; // inAllLibs: in 'All Libs'('Files') page
|
||||
const { items } = this.state;
|
||||
@@ -87,7 +77,6 @@ class SharedLibraries extends Component {
|
||||
sortBy={this.state.sortBy}
|
||||
sortOrder={this.state.sortOrder}
|
||||
sortItems={this.sortItems}
|
||||
onMonitorRepo={this.onMonitorRepo}
|
||||
inAllLibs={inAllLibs}
|
||||
currentViewMode={currentViewMode}
|
||||
/>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||
import { DropdownItem } from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
@@ -10,7 +10,6 @@ import { Utils } from '../../utils/utils';
|
||||
import toaster from '../../components/toast';
|
||||
import ModalPortal from '../../components/modal-portal';
|
||||
import ShareDialog from '../../components/dialog/share-dialog';
|
||||
import RepoMonitoredIcon from '../../components/repo-monitored-icon';
|
||||
import MobileItemMenu from '../../components/mobile-item-menu';
|
||||
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
||||
|
||||
@@ -124,26 +123,6 @@ class Item extends Component {
|
||||
navigate(this.repoURL);
|
||||
};
|
||||
|
||||
watchFileChanges = () => {
|
||||
const { data: repo } = this.props;
|
||||
seafileAPI.monitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, true);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
unwatchFileChanges = () => {
|
||||
const { data: repo } = this.props;
|
||||
seafileAPI.unMonitorRepo(repo.repo_id).then(() => {
|
||||
this.props.onMonitorRepo(repo, false);
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
handleContextMenu = (event) => {
|
||||
this.props.onContextMenu(event, this.props.data);
|
||||
};
|
||||
@@ -156,12 +135,6 @@ class Item extends Component {
|
||||
case 'Unshare':
|
||||
this.leaveShare(event);
|
||||
break;
|
||||
case 'Watch File Changes':
|
||||
this.watchFileChanges();
|
||||
break;
|
||||
case 'Unwatch File Changes':
|
||||
this.unwatchFileChanges();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -182,9 +155,6 @@ class Item extends Component {
|
||||
let leaveShareIconClassName = 'op-icon sf2-icon-x3' + iconVisibility;
|
||||
let shareRepoUrl = this.repoURL = `${siteRoot}library/${data.repo_id}/${Utils.encodePath(data.repo_name)}/`;
|
||||
|
||||
// at present, only repo shared with 'r', 'rw' can be monitored.(Fri Feb 10 16:24:49 CST 2023)
|
||||
const enableMonitorRepo = isPro && (data.permission == 'r' || data.permission == 'rw');
|
||||
|
||||
if (this.props.isDesktop) {
|
||||
return (
|
||||
<Fragment>
|
||||
@@ -204,7 +174,6 @@ class Item extends Component {
|
||||
<td>
|
||||
<Fragment>
|
||||
<Link to={shareRepoUrl}>{data.repo_name}</Link>
|
||||
{data.monitored && <RepoMonitoredIcon repoID={data.repo_id} className="ml-1 op-icon" />}
|
||||
</Fragment>
|
||||
</td>
|
||||
<td>
|
||||
@@ -213,23 +182,6 @@ class Item extends Component {
|
||||
<a href="#" className={shareIconClassName} title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.share}></a>
|
||||
}
|
||||
<a href="#" className={leaveShareIconClassName} title={gettext('Leave Share')} role="button" aria-label={gettext('Leave Share')} onClick={this.leaveShare}></a>
|
||||
{enableMonitorRepo &&
|
||||
<Dropdown isOpen={this.state.isOpMenuOpen} toggle={this.toggleOpMenu}>
|
||||
<DropdownToggle
|
||||
tag="i"
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
className={`op-icon sf3-font-more sf3-font ${iconVisibility}`}
|
||||
title={gettext('More operations')}
|
||||
aria-label={gettext('More operations')}
|
||||
data-toggle="dropdown"
|
||||
aria-expanded={this.state.isOpMenuOpen}
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownItem onClick={data.monitored ? this.unwatchFileChanges : this.watchFileChanges}>{data.monitored ? gettext('Unwatch File Changes') : gettext('Watch File Changes')}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
<td>{data.size}</td>
|
||||
@@ -257,7 +209,6 @@ class Item extends Component {
|
||||
>
|
||||
</i>
|
||||
}
|
||||
{data.monitored && <RepoMonitoredIcon repoID={data.repo_id} className="op-icon library-grid-item-icon" />}
|
||||
</div>
|
||||
|
||||
<div className="flex-shrink-0 d-flex align-items-center">
|
||||
@@ -265,23 +216,6 @@ class Item extends Component {
|
||||
<a href="#" className={shareIconClassName} title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.share}></a>
|
||||
}
|
||||
<a href="#" className={leaveShareIconClassName} title={gettext('Leave Share')} role="button" aria-label={gettext('Leave Share')} onClick={this.leaveShare}></a>
|
||||
{enableMonitorRepo &&
|
||||
<Dropdown isOpen={this.state.isOpMenuOpen} toggle={this.toggleOpMenu}>
|
||||
<DropdownToggle
|
||||
tag="i"
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
className={`op-icon sf3-font-more sf3-font ${iconVisibility}`}
|
||||
title={gettext('More operations')}
|
||||
aria-label={gettext('More operations')}
|
||||
data-toggle="dropdown"
|
||||
aria-expanded={this.state.isOpMenuOpen}
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownItem onClick={data.monitored ? this.unwatchFileChanges : this.watchFileChanges}>{data.monitored ? gettext('Unwatch File Changes') : gettext('Watch File Changes')}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -310,7 +244,6 @@ class Item extends Component {
|
||||
<td onClick={this.visitRepo}><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
|
||||
<td onClick={this.visitRepo}>
|
||||
<Link to={shareRepoUrl}>{data.repo_name}</Link>
|
||||
{data.monitored && <RepoMonitoredIcon repoID={data.repo_id} className="ml-1 op-icon" />}
|
||||
<br />
|
||||
<span className="item-meta-info" title={data.owner_contact_email}>{data.owner_name}</span>
|
||||
<span className="item-meta-info">{data.size}</span>
|
||||
@@ -325,14 +258,6 @@ class Item extends Component {
|
||||
<DropdownItem className="mobile-menu-item" onClick={this.share}>{gettext('Share')}</DropdownItem>
|
||||
}
|
||||
<DropdownItem className="mobile-menu-item" onClick={this.leaveShare}>{gettext('Leave Share')}</DropdownItem>
|
||||
{enableMonitorRepo &&
|
||||
<DropdownItem
|
||||
className="mobile-menu-item"
|
||||
onClick={data.monitored ? this.unwatchFileChanges : this.watchFileChanges}
|
||||
>
|
||||
{data.monitored ? gettext('Unwatch File Changes') : gettext('Watch File Changes')}
|
||||
</DropdownItem>
|
||||
}
|
||||
</MobileItemMenu>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -364,7 +289,6 @@ Item.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
isItemFreezed: PropTypes.bool.isRequired,
|
||||
freezeItem: PropTypes.func.isRequired,
|
||||
onMonitorRepo: PropTypes.func.isRequired,
|
||||
onContextMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
@@ -181,14 +181,6 @@ const TextTranslation = {
|
||||
key: 'Reset Password',
|
||||
value: gettext('Reset Password')
|
||||
},
|
||||
UNWATCH_FILE_CHANGES: {
|
||||
key: 'Unwatch File Changes',
|
||||
value: gettext('Unwatch File Changes')
|
||||
},
|
||||
WATCH_FILE_CHANGES: {
|
||||
key: 'Watch File Changes',
|
||||
value: gettext('Watch File Changes')
|
||||
},
|
||||
ADVANCED: {
|
||||
key: 'advanced',
|
||||
value: gettext('Advanced')
|
||||
|
@@ -721,7 +721,7 @@ export const Utils = {
|
||||
const showResetPasswordMenuItem = isPro && repo.encrypted && enableResetEncryptedRepoPassword && isEmailConfigured;
|
||||
const operations = [];
|
||||
const DIVIDER = 'Divider';
|
||||
const { SHARE, DELETE, RENAME, TRANSFER, FOLDER_PERMISSION, SHARE_ADMIN, CHANGE_PASSWORD, RESET_PASSWORD, UNWATCH_FILE_CHANGES, WATCH_FILE_CHANGES, ADVANCED } = TextTranslation;
|
||||
const { SHARE, DELETE, RENAME, TRANSFER, FOLDER_PERMISSION, SHARE_ADMIN, CHANGE_PASSWORD, RESET_PASSWORD, ADVANCED } = TextTranslation;
|
||||
|
||||
operations.push(SHARE, DELETE, DIVIDER, RENAME, TRANSFER);
|
||||
|
||||
@@ -738,11 +738,6 @@ export const Utils = {
|
||||
operations.push(RESET_PASSWORD);
|
||||
}
|
||||
|
||||
if (isPro) {
|
||||
const monitorOp = repo.monitored ? UNWATCH_FILE_CHANGES : WATCH_FILE_CHANGES;
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
|
||||
operations.push(DIVIDER);
|
||||
const subOpList = Utils.getAdvancedOperations();
|
||||
operations.push({ ...ADVANCED, subOpList });
|
||||
@@ -765,7 +760,7 @@ export const Utils = {
|
||||
},
|
||||
|
||||
getSharedLibsOperationList: function (lib) {
|
||||
const { SHARE, UNSHARE, WATCH_FILE_CHANGES, UNWATCH_FILE_CHANGES } = TextTranslation;
|
||||
const { SHARE, UNSHARE } = TextTranslation;
|
||||
const operations = [];
|
||||
|
||||
if (isPro && lib.is_admin) {
|
||||
@@ -773,9 +768,6 @@ export const Utils = {
|
||||
}
|
||||
operations.push(UNSHARE);
|
||||
|
||||
const monitorOp = lib.monitored ? UNWATCH_FILE_CHANGES : WATCH_FILE_CHANGES;
|
||||
operations.push(monitorOp);
|
||||
|
||||
return operations;
|
||||
},
|
||||
|
||||
@@ -793,7 +785,7 @@ export const Utils = {
|
||||
|
||||
getSharedRepoOperationList: function (repo, currentGroup, isPublic) {
|
||||
const operations = [];
|
||||
const { SHARE, UNSHARE, DELETE, RENAME, FOLDER_PERMISSION, SHARE_ADMIN, UNWATCH_FILE_CHANGES, WATCH_FILE_CHANGES, ADVANCED, CHANGE_PASSWORD, RESET_PASSWORD, API_TOKEN } = TextTranslation;
|
||||
const { SHARE, UNSHARE, DELETE, RENAME, FOLDER_PERMISSION, SHARE_ADMIN, ADVANCED, CHANGE_PASSWORD, RESET_PASSWORD, API_TOKEN } = TextTranslation;
|
||||
|
||||
const isStaff = currentGroup && currentGroup.admins && currentGroup.admins.indexOf(username) > -1;
|
||||
const isRepoOwner = repo.owner_email === username;
|
||||
@@ -823,16 +815,12 @@ export const Utils = {
|
||||
if (repo.encrypted && enableResetEncryptedRepoPassword && isEmailConfigured) {
|
||||
operations.push(RESET_PASSWORD);
|
||||
}
|
||||
if (repo.permission === 'r' || repo.permission === 'rw') {
|
||||
const monitorOp = repo.monitored ? UNWATCH_FILE_CHANGES : WATCH_FILE_CHANGES;
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
if (Utils.isDesktop()) {
|
||||
operations.push(DIVIDER);
|
||||
const subOpList = [API_TOKEN];
|
||||
operations.push({ ...ADVANCED, subOpList });
|
||||
}
|
||||
return operations;
|
||||
return operations.filter((op, i, arr) => !(op === DIVIDER && arr[i + 1] === DIVIDER));
|
||||
} else {
|
||||
operations.push(UNSHARE);
|
||||
}
|
||||
@@ -845,10 +833,6 @@ export const Utils = {
|
||||
operations.push(UNSHARE);
|
||||
}
|
||||
}
|
||||
if (repo.permission === 'r' || repo.permission === 'rw') {
|
||||
const monitorOp = repo.monitored ? UNWATCH_FILE_CHANGES : WATCH_FILE_CHANGES;
|
||||
operations.push(monitorOp);
|
||||
}
|
||||
} else {
|
||||
if (isRepoOwner) {
|
||||
operations.push(SHARE);
|
||||
|
Reference in New Issue
Block a user