1
0
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:
llj
2025-06-16 10:45:41 +08:00
committed by GitHub
parent 9b293072c3
commit ff776790ca
18 changed files with 108 additions and 379 deletions

View File

@@ -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>

View File

@@ -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 });
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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}
/>

View File

@@ -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}
/>

View File

@@ -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>

View File

@@ -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}

View File

@@ -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}
/>

View File

@@ -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 &&

View File

@@ -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}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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}
/>

View File

@@ -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,
};

View File

@@ -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')

View File

@@ -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);