1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-24 04:48:03 +00:00

Library view more menu (#7806)

* [library view] added the 'More' menu('more' operations for the current library)

* add monitored field when get repo info

---------

Co-authored-by: lian <imwhatiam123@gmail.com>
This commit is contained in:
llj
2025-05-12 16:54:52 +08:00
committed by GitHub
parent feccf82d97
commit 00119b4e6b
18 changed files with 445 additions and 54 deletions

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalBody, ModalFooter, Alert } from 'reactstrap';
import { Button, Modal, ModalBody, ModalFooter, Alert } from 'reactstrap';
import { gettext, repoPasswordMinLength } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import { seafileAPI } from '../../utils/seafile-api';
@@ -137,6 +137,7 @@ class ChangeRepoPasswordDialog extends React.Component {
</form>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.props.toggleDialog}>{gettext('Cancel')}</Button>
<button className="btn btn-primary" disabled={this.state.submitBtnDisabled} onClick={this.formSubmit}>{gettext('Submit')}</button>
</ModalFooter>
</Modal>

View File

@@ -0,0 +1,76 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import { validateName } from '../../utils/utils';
import { Button, Input, Label, Modal, ModalBody, ModalFooter, Alert } from 'reactstrap';
import SeahubModalHeader from '@/components/common/seahub-modal-header';
const propTypes = {
renameRepo: PropTypes.func.isRequired,
toggleDialog: PropTypes.func.isRequired
};
class Rename extends React.Component {
constructor(props) {
super(props);
this.state = {
name: props.name,
errMessage: '',
isSubmitBtnActive: false
};
}
handleChange = (e) => {
if (!e.target.value.trim()) {
this.setState({ isSubmitBtnActive: false });
} else {
this.setState({ isSubmitBtnActive: true });
}
this.setState({ name: e.target.value });
};
handleSubmit = () => {
let name = this.state.name.trim();
let { isValid, errMessage } = validateName(name);
if (!isValid) {
this.setState({ errMessage });
return;
}
this.props.renameRepo(name);
this.toggle();
};
handleKeyDown = (e) => {
if (e.key === 'Enter') {
e.preventDefault();
this.handleSubmit();
}
};
toggle = () => {
this.props.toggleDialog();
};
render() {
return (
<Modal isOpen={true} toggle={this.toggle}>
<SeahubModalHeader toggle={this.toggle}>{gettext('Rename Library')}</SeahubModalHeader>
<ModalBody>
<Label for="repo-name">{gettext('Name')}</Label>
<Input id="repo-name" onKeyDown={this.handleKeyDown} value={this.state.name} onChange={this.handleChange} />
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit} disabled={!this.state.isSubmitBtnActive}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
Rename.propTypes = propTypes;
export default Rename;

View File

@@ -1,20 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Modal, ModalBody, ModalFooter, TabContent, TabPane } from 'reactstrap';
import SeahubModalHeader from '../common/seahub-modal-header';
import makeAnimated from 'react-select/animated';
import toaster from '../toast';
import { userAPI } from '../../utils/user-api';
import { gettext, isPro } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import toaster from '../toast';
import { SeahubSelect } from '../common/select';
import SeahubModalHeader from '../common/seahub-modal-header';
import '../../css/repo-office-suite-dialog.css';
const propTypes = {
itemName: PropTypes.string.isRequired,
toggleDialog: PropTypes.func.isRequired,
submit: PropTypes.func.isRequired,
repoID: PropTypes.string.isRequired,
repoName: PropTypes.string.isRequired,
toggleDialog: PropTypes.func.isRequired
};
class OfficeSuiteDialog extends React.Component {
@@ -32,8 +32,21 @@ class OfficeSuiteDialog extends React.Component {
};
submit = () => {
let suite_id = this.state.selectedOption.value;
this.props.submit(suite_id);
const { repoID } = this.props;
const { selectedOption } = this.state;
if (!selectedOption) {
return false;
}
const { value: suiteID } = selectedOption;
userAPI.setOfficeSuite(repoID, suiteID).then(res => {
const message = gettext('Successfully changed the office suite.');
toaster.success(message);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
this.props.toggleDialog();
};
componentDidMount() {
@@ -72,7 +85,7 @@ class OfficeSuiteDialog extends React.Component {
maxMenuHeight={200}
hideSelectedOptions={true}
components={makeAnimated()}
placeholder={gettext('Select a office suite')}
placeholder={gettext('Select an office suite')}
options={this.options}
onChange={this.handleSelectChange}
value={this.state.selectedOption}
@@ -86,7 +99,7 @@ class OfficeSuiteDialog extends React.Component {
};
render() {
const { itemName: repoName } = this.props;
const { repoName } = this.props;
let title = gettext('{library_name} Office Suite');
title = title.replace('{library_name}', '<span class="op-target text-truncate mx-1">' + Utils.HTMLescape(repoName) + '</span>');
return (

View File

@@ -66,6 +66,7 @@ class TransferDialog extends React.Component {
const { activeTab, reshare, selectedOption, selectedUsers } = this.state;
const email = activeTab === TRANS_DEPART ? selectedOption.value : selectedUsers[0].email;
this.props.onTransferRepo(email, reshare);
this.props.toggleDialog();
};
componentDidMount() {

View File

@@ -33,6 +33,7 @@ const propTypes = {
getMenuContainerSize: PropTypes.func,
updateDirent: PropTypes.func,
updateTreeNode: PropTypes.func,
updateRepoInfo: PropTypes.func
};
class DirColumnNav extends React.Component {
@@ -76,7 +77,7 @@ class DirColumnNav extends React.Component {
/>
<DirViews repoID={repoID} currentPath={currentPath} userPerm={userPerm} currentRepoInfo={currentRepoInfo} />
<DirTags repoID={repoID} currentPath={currentPath} userPerm={userPerm} currentRepoInfo={currentRepoInfo} />
<DirOthers repoID={repoID} userPerm={userPerm} currentRepoInfo={currentRepoInfo} />
<DirOthers repoID={repoID} userPerm={userPerm} currentRepoInfo={currentRepoInfo} updateRepoInfo={this.props.updateRepoInfo} />
</>
)}
</div>

View File

@@ -86,6 +86,7 @@ const propTypes = {
updateCurrentPath: PropTypes.func,
toggleShowDirentToolbar: PropTypes.func,
updateTreeNode: PropTypes.func,
updateRepoInfo: PropTypes.func
};
class DirColumnView extends React.Component {
@@ -177,6 +178,7 @@ class DirColumnView extends React.Component {
navRate={navRate}
inResizing={inResizing}
currentRepoInfo={this.props.currentRepoInfo}
updateRepoInfo={this.props.updateRepoInfo}
onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy}
selectedDirentList={this.props.selectedDirentList}

View File

@@ -7,6 +7,7 @@
align-items: center;
}
.dir-others .dir-others-item[aria-expanded="true"], /* for 'More' */
.dir-others .dir-others-item:hover {
background-color: #f0f0f0;
border-radius: 0.25rem;

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../../utils/constants';
import { gettext, username } from '../../../utils/constants';
import { Utils } from '../../../utils/utils';
import TreeSection from '../../tree-section';
import TrashDialog from '../../dialog/trash-dialog';
@@ -9,13 +9,14 @@ import RepoHistoryDialog from '../../dialog/repo-history';
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 './index.css';
const DirOthers = ({ userPerm, repoID, currentRepoInfo }) => {
const DirOthers = ({ userPerm, repoID, currentRepoInfo, updateRepoInfo }) => {
const { owner_email, is_admin, repo_name: repoName } = currentRepoInfo;
const showSettings = currentRepoInfo.is_admin; // repo owner, department admin, shared with 'Admin' permission
const repoName = currentRepoInfo.repo_name;
const showSettings = is_admin; // repo owner, department admin, shared with 'Admin' permission
let [isSettingsDialogOpen, setSettingsDialogOpen] = useState(false);
let [activeTab, setActiveTab] = useState(TAB.HISTORY_SETTING);
let [showMigrateTip, setShowMigrateTip] = useState(false);
@@ -51,6 +52,9 @@ const DirOthers = ({ userPerm, repoID, currentRepoInfo }) => {
setRepoHistoryDialogOpen(!isRepoHistoryDialogOpen);
};
const isDesktop = Utils.isDesktop();
const isRepoOwner = owner_email == username;
return (
<TreeSection title={gettext('Others')} className="dir-others">
{showSettings && (
@@ -65,12 +69,18 @@ const DirOthers = ({ userPerm, repoID, currentRepoInfo }) => {
<span className="dir-others-item-text">{gettext('Trash')}</span>
</div>
)}
{Utils.isDesktop() && (
{isDesktop && (
<div className='dir-others-item text-nowrap' title={gettext('History')} onClick={toggleRepoHistoryDialog}>
<span className="sf3-font-history sf3-font"></span>
<span className="dir-others-item-text">{gettext('History')}</span>
</div>
)}
{isDesktop && isRepoOwner && (
<LibraryMoreOperations
repo={currentRepoInfo}
updateRepoInfo={updateRepoInfo}
/>
)}
{showTrashDialog && (
<TrashDialog
repoID={repoID}
@@ -105,6 +115,7 @@ DirOthers.propTypes = {
userPerm: PropTypes.string,
repoID: PropTypes.string,
currentRepoInfo: PropTypes.object.isRequired,
updateRepoInfo: PropTypes.func
};
export default DirOthers;

View File

@@ -0,0 +1,278 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { navigate } from '@gatsbyjs/reach-router';
import { Utils } from '../../../utils/utils';
import { seafileAPI } from '../../../utils/seafile-api';
import { gettext, siteRoot } from '../../../utils/constants';
import ModalPortal from '../../../components/modal-portal';
import toaster from '../../../components/toast';
import RenameRepoDialog from '../../../components/dialog/rename-repo';
import TransferDialog from '../../../components/dialog/transfer-dialog';
import ChangeRepoPasswordDialog from '../../../components/dialog/change-repo-password-dialog';
import ResetEncryptedRepoPasswordDialog from '../../../components/dialog/reset-encrypted-repo-password-dialog';
import LabelRepoStateDialog from '../../../components/dialog/label-repo-state-dialog';
import LibSubFolderPermissionDialog from '../../../components/dialog/lib-sub-folder-permission-dialog';
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 = {
repo: PropTypes.object.isRequired,
updateRepoInfo: PropTypes.func.isRequired
};
class LibraryMoreOperations extends React.Component {
constructor(props) {
super(props);
this.state = {
isRenameRepoDialogOpen: false,
isTransferDialogOpen: false,
isChangePasswordDialogOpen: false,
isResetPasswordDialogOpen: false,
isLabelRepoStateDialogOpen: false,
isFolderPermissionDialogOpen: false,
isAPITokenDialogOpen: false,
isRepoShareAdminDialogOpen: false,
isOfficeSuiteDialogOpen: false
};
}
onMenuItemClick = (item) => {
switch (item) {
case 'Rename':
this.onRenameToggle();
break;
case 'Transfer':
this.onTransferToggle();
break;
case 'Folder Permission':
this.onFolderPermissionToggle();
break;
case 'Share Admin':
this.toggleRepoShareAdminDialog();
break;
case 'Change Password':
this.onChangePasswordToggle();
break;
case 'Reset Password':
this.onResetPasswordToggle();
break;
case 'Watch File Changes':
this.watchFileChanges();
break;
case 'Unwatch File Changes':
this.unwatchFileChanges();
break;
case 'API Token':
this.onAPITokenToggle();
break;
case 'Label Current State':
this.onLabelToggle();
break;
case 'Office Suite':
this.onOfficeSuiteToggle();
break;
default:
break;
}
};
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 });
};
onTransferToggle = () => {
this.setState({ isTransferDialogOpen: !this.state.isTransferDialogOpen });
};
onChangePasswordToggle = () => {
this.setState({ isChangePasswordDialogOpen: !this.state.isChangePasswordDialogOpen });
};
onResetPasswordToggle = () => {
this.setState({ isResetPasswordDialogOpen: !this.state.isResetPasswordDialogOpen });
};
onLabelToggle = () => {
this.setState({ isLabelRepoStateDialogOpen: !this.state.isLabelRepoStateDialogOpen });
};
onFolderPermissionToggle = () => {
this.setState({ isFolderPermissionDialogOpen: !this.state.isFolderPermissionDialogOpen });
};
onAPITokenToggle = () => {
this.setState({ isAPITokenDialogOpen: !this.state.isAPITokenDialogOpen });
};
onOfficeSuiteToggle = () => {
this.setState({ isOfficeSuiteDialogOpen: !this.state.isOfficeSuiteDialogOpen });
};
toggleRepoShareAdminDialog = () => {
this.setState({ isRepoShareAdminDialogOpen: !this.state.isRepoShareAdminDialogOpen });
};
renameRepo = (newName) => {
const { repo } = this.props;
const { repo_id: repoID } = repo;
seafileAPI.renameRepo(repoID, newName).then((res) => {
this.props.updateRepoInfo({ 'repo_name': newName });
const message = gettext('Successfully renamed the library.');
toaster.success(message);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onTransferRepo = (email, reshare) => {
const { repo } = this.props;
const { repo_id: repoID } = repo;
userAPI.transferRepo(repoID, email, reshare).then(res => {
const message = gettext('Successfully transferred the library.');
toaster.success(message);
navigate(siteRoot);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
render() {
const { repo } = this.props;
const {
isRenameRepoDialogOpen, isTransferDialogOpen
} = this.state;
return (
<Fragment>
<MylibRepoMenu
isPC={true}
isLibView={true}
repo={repo}
onMenuItemClick={this.onMenuItemClick}
>
<>
<span className="sf3-font-more sf3-font"></span>
<span className="dir-others-item-text">{gettext('More')}</span>
</>
</MylibRepoMenu>
{isRenameRepoDialogOpen && (
<ModalPortal>
<RenameRepoDialog
name={repo.repo_name}
renameRepo={this.renameRepo}
toggleDialog={this.onRenameToggle}
/>
</ModalPortal>
)}
{isTransferDialogOpen && (
<ModalPortal>
<TransferDialog
itemName={repo.repo_name}
onTransferRepo={this.onTransferRepo}
toggleDialog={this.onTransferToggle}
/>
</ModalPortal>
)}
{this.state.isChangePasswordDialogOpen && (
<ModalPortal>
<ChangeRepoPasswordDialog
repoID={repo.repo_id}
repoName={repo.repo_name}
toggleDialog={this.onChangePasswordToggle}
/>
</ModalPortal>
)}
{this.state.isResetPasswordDialogOpen && (
<ModalPortal>
<ResetEncryptedRepoPasswordDialog
repoID={repo.repo_id}
toggleDialog={this.onResetPasswordToggle}
/>
</ModalPortal>
)}
{this.state.isLabelRepoStateDialogOpen && (
<ModalPortal>
<LabelRepoStateDialog
repoID={repo.repo_id}
repoName={repo.repo_name}
toggleDialog={this.onLabelToggle}
/>
</ModalPortal>
)}
{this.state.isFolderPermissionDialogOpen && (
<ModalPortal>
<LibSubFolderPermissionDialog
toggleDialog={this.onFolderPermissionToggle}
repoID={repo.repo_id}
repoName={repo.repo_name}
/>
</ModalPortal>
)}
{this.state.isAPITokenDialogOpen && (
<ModalPortal>
<RepoAPITokenDialog
repo={repo}
onRepoAPITokenToggle={this.onAPITokenToggle}
/>
</ModalPortal>
)}
{this.state.isRepoShareAdminDialogOpen && (
<ModalPortal>
<RepoShareAdminDialog
repo={repo}
toggleDialog={this.toggleRepoShareAdminDialog}
/>
</ModalPortal>
)}
{this.state.isOfficeSuiteDialogOpen && (
<ModalPortal>
<OfficeSuiteDialog
repoID={repo.repo_id}
repoName={repo.repo_name}
toggleDialog={this.onOfficeSuiteToggle}
/>
</ModalPortal>
)}
</Fragment>
);
}
}
LibraryMoreOperations.propTypes = propTypes;
export default LibraryMoreOperations;

View File

@@ -245,7 +245,6 @@ class SharedRepoListItem extends React.Component {
toaster.danger(gettext('Failed. Please check the network.'), { duration: 3 });
}
});
this.onTransferToggle();
};
onRenameConfirm = (name) => {

View File

@@ -24,6 +24,7 @@ class RepoInfo {
this.last_modified = object.last_modified;
this.status = object.status;
this.enable_onlyoffice = object.enable_onlyoffice;
this.monitored = object.monitored;
}
}

View File

@@ -2274,6 +2274,12 @@ class LibContentView extends React.Component {
this.props.eventBus.dispatch(EVENT_BUS_TYPE.TAGS_CHANGED, tags);
};
updateRepoInfo = (updatedData) => {
this.setState({
currentRepoInfo: { ...this.state.currentRepoInfo, ...updatedData }
});
};
render() {
const { repoID } = this.props;
let { currentRepoInfo, userPerm, isCopyMoveProgressDialogShow, isDeleteFolderDialogOpen, errorMsg,
@@ -2464,6 +2470,7 @@ class LibContentView extends React.Component {
path={this.state.path}
repoID={this.props.repoID}
currentRepoInfo={this.state.currentRepoInfo}
updateRepoInfo={this.updateRepoInfo}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
userPerm={userPerm}
enableDirPrivateShare={enableDirPrivateShare}

View File

@@ -273,22 +273,6 @@ class MylibRepoListItem extends React.Component {
toaster.danger(gettext('Failed. Please check the network.'), { duration: 3 });
}
});
this.onTransferToggle();
};
onOfficeSuiteChange = (suiteID) => {
let repoID = this.props.repo.repo_id;
userAPI.setOfficeSuite(repoID, suiteID).then(res => {
let message = gettext('Successfully change office suite.');
toaster.success(message);
}).catch(error => {
if (error.response) {
toaster.danger(error.response.data.error_msg || gettext('Error'), { duration: 3 });
} else {
toaster.danger(gettext('Failed. Please check the network.'), { duration: 3 });
}
});
this.onOfficeSuiteToggle();
};
onDeleteRepo = (repo) => {
@@ -578,8 +562,7 @@ class MylibRepoListItem extends React.Component {
<ModalPortal>
<OfficeSuiteDialog
repoID={repo.repo_id}
itemName={repo.repo_name}
submit={this.onOfficeSuiteChange}
repoName={repo.repo_name}
toggleDialog={this.onOfficeSuiteToggle}
/>
</ModalPortal>

View File

@@ -9,8 +9,8 @@ const propTypes = {
isPC: PropTypes.bool,
repo: PropTypes.object.isRequired,
isStarred: PropTypes.bool,
onFreezedItem: PropTypes.func.isRequired,
onUnfreezedItem: PropTypes.func.isRequired,
onFreezedItem: PropTypes.func,
onUnfreezedItem: PropTypes.func,
onMenuItemClick: PropTypes.func.isRequired,
};
@@ -25,7 +25,7 @@ class MylibRepoMenu extends React.Component {
}
onMenuItemClick = (e) => {
let operation = Utils.getEventData(e, 'toggle');
const operation = Utils.getEventData(e, 'toggle');
this.props.onMenuItemClick(operation);
};
@@ -46,6 +46,12 @@ class MylibRepoMenu extends React.Component {
};
toggleOperationMenu = (e) => {
const { isLibView } = this.props;
if (isLibView) {
this.setState({ isItemMenuShow: !this.state.isItemMenuShow });
return;
}
let dataset = e.target ? e.target.dataset : null;
if (dataset && dataset.toggle && dataset.toggle === 'Rename') {
this.setState({ isItemMenuShow: !this.state.isItemMenuShow });
@@ -175,9 +181,6 @@ class MylibRepoMenu extends React.Component {
case 'Advanced':
translateResult = gettext('Advanced');
break;
case 'SeaTable integration':
translateResult = gettext('SeaTable integration');
break;
case 'Office Suite':
translateResult = gettext('Office Suite');
break;
@@ -192,22 +195,31 @@ class MylibRepoMenu extends React.Component {
let operations = this.generatorOperations();
const advancedOperations = this.getAdvancedOperations();
const { children, isLibView } = this.props;
// pc menu
if (this.props.isPC) {
return (
<Dropdown isOpen={this.state.isItemMenuShow} toggle={this.toggleOperationMenu}>
<Dropdown
isOpen={this.state.isItemMenuShow}
toggle={this.toggleOperationMenu}
direction={isLibView ? 'end' : 'down'}
className={isLibView ? 'd-block' : ''}
>
<DropdownToggle
tag="i"
tag={isLibView ? 'div' : 'span'}
className={isLibView ? 'dir-others-item' : ''}
role="button"
tabIndex="0"
className="sf-dropdown-toggle sf3-font-more sf3-font"
title={gettext('More operations')}
title={isLibView ? gettext('More') : gettext('More operations')}
aria-label={gettext('More operations')}
onClick={this.onDropdownToggleClick}
onKeyDown={this.onDropdownToggleKeyDown}
data-toggle="dropdown"
/>
<DropdownMenu onMouseMove={this.onDropDownMouseMove}>
>
{children || <i className="sf-dropdown-toggle sf3-font-more sf3-font"></i>}
</DropdownToggle>
<DropdownMenu onMouseMove={this.onDropDownMouseMove} container={isLibView ? 'body' : ''}>
{operations.map((item, index) => {
if (item == 'Divider') {
return <DropdownItem key={index} divider />;

View File

@@ -223,7 +223,6 @@ class RepoItem extends React.Component {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
this.toggleTransfer();
};
render() {

View File

@@ -180,7 +180,6 @@ class Item extends Component {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
this.toggleTransferDialog();
};
handleMouseOver = () => {

View File

@@ -138,8 +138,7 @@ class Item extends Component {
};
transferRepo = (owner, reshare) => {
this.props.transferRepo(this.props.item.id, owner.email, reshare);
this.toggleTransferDialog();
this.props.transferRepo(this.props.item.id, owner, reshare);
};
renderRepoName = () => {

View File

@@ -395,6 +395,12 @@ class RepoView(APIView):
has_been_shared_out = False
logger.error(e)
monitored = False
monitored_repos = UserMonitoredRepos.objects.filter(email=username,
repo_id=repo_id)
if monitored_repos:
monitored = True
result = {
"repo_id": repo.id,
"repo_name": repo.name,
@@ -416,7 +422,8 @@ class RepoView(APIView):
"lib_need_decrypt": lib_need_decrypt,
"last_modified": timestamp_to_isoformat_timestr(repo.last_modify),
"status": normalize_repo_status_code(repo.status),
"enable_onlyoffice": enable_onlyoffice
"enable_onlyoffice": enable_onlyoffice,
"monitored": monitored,
}
return Response(result)
@@ -542,6 +549,7 @@ class RepoShareInfoView(APIView):
return Response(result)
class RepoImageRotateView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )