diff --git a/frontend/src/components/dialog/share-dialog.js b/frontend/src/components/dialog/share-dialog.js
index 72eb726b18..5936d8986b 100644
--- a/frontend/src/components/dialog/share-dialog.js
+++ b/frontend/src/components/dialog/share-dialog.js
@@ -1,11 +1,13 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
-import { gettext, canGenerateShareLink, canGenerateUploadLink } from '../../utils/constants';
+import { gettext, username, canGenerateShareLink, canGenerateUploadLink } from '../../utils/constants';
import ShareToUser from './share-to-user';
import ShareToGroup from './share-to-group';
import GenerateShareLink from './generate-share-link';
import GenerateUploadLink from './generate-upload-link';
+import { seafileAPI } from '../../utils/seafile-api';
+import Loading from '../loading';
import '../../css/share-link-dialog.css';
const propTypes = {
@@ -24,10 +26,23 @@ class ShareDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
- activeTab: this.getInitialActiveTab()
+ activeTab: this.getInitialActiveTab(),
+ isRepoJudgemented: false,
+ isRepoOwner: false,
};
}
+ componentDidMount() {
+ let repoID = this.props.repoID;
+ seafileAPI.getRepoInfo(repoID).then(res => {
+ let isRepoOwner = res.data.owner_email === username;
+ this.setState({
+ isRepoJudgemented: true,
+ isRepoOwner: isRepoOwner,
+ });
+ });
+ }
+
getInitialActiveTab = () => {
const {repoEncrypted, userPerm, enableDirPrivateShare} = this.props;
const enableShareLink = !repoEncrypted && canGenerateShareLink;
@@ -49,8 +64,12 @@ class ShareDialog extends React.Component {
}
renderDirContent = () => {
- let activeTab = this.state.activeTab;
+ if (!this.state.isRepoJudgemented) {
+ return ;
+ }
+
+ let activeTab = this.state.activeTab;
const {repoEncrypted, userPerm, enableDirPrivateShare} = this.props;
const enableShareLink = !repoEncrypted && canGenerateShareLink;
const enableUploadLink = !repoEncrypted && canGenerateUploadLink && userPerm == 'rw';
@@ -112,10 +131,10 @@ class ShareDialog extends React.Component {
{enableDirPrivateShare &&
-
+
-
+
}
diff --git a/frontend/src/components/dialog/share-to-group.js b/frontend/src/components/dialog/share-to-group.js
index ade573abbe..1621d0ac7e 100644
--- a/frontend/src/components/dialog/share-to-group.js
+++ b/frontend/src/components/dialog/share-to-group.js
@@ -36,6 +36,7 @@ class GroupItem extends React.Component {
render() {
let item = this.props.item;
+ let currentPermission = item.is_admin ? 'admin' : item.permission;
return (
{item.group_info.name} |
@@ -43,7 +44,7 @@ class GroupItem extends React.Component {
@@ -87,7 +88,8 @@ const propTypes = {
isGroupOwnedRepo: PropTypes.bool,
itemPath: PropTypes.string.isRequired,
itemType: PropTypes.string.isRequired,
- repoID: PropTypes.string.isRequired
+ repoID: PropTypes.string.isRequired,
+ isRepoOwner: PropTypes.bool.isRequired,
};
const NoOptionsMessage = (props) => {
@@ -108,9 +110,10 @@ class ShareToGroup extends React.Component {
};
this.options = [];
this.permissions = []
- if (this.props.itemType === 'library') {
- this.permissions = ['rw', 'r', 'admin', 'cloud-edit', 'preview'];
- } else if (this.props.itemType === 'dir') {
+ let { itemType, isRepoOwner } = props;
+ if (itemType === 'library') {
+ this.permissions = isRepoOwner ? ['rw', 'r', 'admin', 'cloud-edit', 'preview'] : ['rw', 'r', 'cloud-edit', 'preview'];
+ } else if (itemType === 'dir') {
this.permissions = ['rw', 'r', 'cloud-edit', 'preview'];
}
if (this.props.isGroupOwnedRepo || !isPro) {
@@ -251,6 +254,7 @@ class ShareToGroup extends React.Component {
if (groupID === sharedItemGroupID) {
sharedItem.permission = permission;
}
+ sharedItem.is_admin = permission === 'admin' ? true : false;
return sharedItem;
});
this.setState({sharedItems: sharedItems});
diff --git a/frontend/src/components/dialog/share-to-user.js b/frontend/src/components/dialog/share-to-user.js
index e47c81aece..85b600152e 100644
--- a/frontend/src/components/dialog/share-to-user.js
+++ b/frontend/src/components/dialog/share-to-user.js
@@ -88,7 +88,8 @@ const propTypes = {
isGroupOwnedRepo: PropTypes.bool,
itemPath: PropTypes.string.isRequired,
itemType: PropTypes.string.isRequired,
- repoID: PropTypes.string.isRequired
+ repoID: PropTypes.string.isRequired,
+ isRepoOwner: PropTypes.bool.isRequired,
};
class ShareToUser extends React.Component {
@@ -103,8 +104,9 @@ class ShareToUser extends React.Component {
};
this.options = [];
this.permissions = [];
- if (this.props.itemType === 'library') {
- this.permissions = ['rw', 'r', 'admin', 'cloud-edit', 'preview'];
+ let { itemType, isRepoOwner } = props;
+ if (itemType === 'library') {
+ this.permissions = isRepoOwner ? ['rw', 'r', 'admin', 'cloud-edit', 'preview'] : ['rw', 'r', 'cloud-edit', 'preview'];
} else if (this.props.itemType === 'dir') {
this.permissions = ['rw', 'r', 'cloud-edit', 'preview'];
}
@@ -319,13 +321,13 @@ class ShareToUser extends React.Component {
deleteShareItem={this.deleteShareItem}
onChangeUserPermission={this.onChangeUserPermission}
/>
- { canInvitePeople &&
-
-
- {gettext('Invite People')}
-
- }
+ {canInvitePeople &&
+
+
+ {gettext('Invite People')}
+
+ }
);
diff --git a/frontend/src/components/dirent-grid-view/dirent-grid-view.js b/frontend/src/components/dirent-grid-view/dirent-grid-view.js
index a34b28fc29..f808cce064 100644
--- a/frontend/src/components/dirent-grid-view/dirent-grid-view.js
+++ b/frontend/src/components/dirent-grid-view/dirent-grid-view.js
@@ -392,6 +392,10 @@ class DirentGridView extends React.Component{
menuList: menuList,
};
+ if (menuList.length === 0) {
+ return;
+ }
+
showMenu(showMenuConfig);
}
@@ -408,11 +412,17 @@ class DirentGridView extends React.Component{
let contextmenuList = [];
if (isContextmenu) {
let { SHARE, DOWNLOAD, DELETE } = TextTranslation;
- contextmenuList = this.props.showShareBtn ? [SHARE, DOWNLOAD, DELETE, 'Divider'] : [DOWNLOAD, DELETE, 'Divider'];
+ contextmenuList = this.props.showShareBtn ? [SHARE] : [];
- if (dirent.type === 'file') {
- contextmenuList = canGenerateShareLink ? [SHARE, DOWNLOAD, DELETE, 'Divider'] : [DOWNLOAD, DELETE, 'Divider'];
+ if (dirent.permission === 'rw' || dirent.permission === 'r') {
+ contextmenuList = [...contextmenuList, DOWNLOAD];
}
+
+ if (dirent.permission === 'rw') {
+ contextmenuList = [...contextmenuList, DELETE];
+ }
+
+ contextmenuList = [...contextmenuList, 'Divider'];
}
let { RENAME, MOVE, COPY, PERMISSION, OPEN_VIA_CLIENT, LOCK, UNLOCK, COMMENT, HISTORY, ACCESS_LOG } = TextTranslation;
diff --git a/frontend/src/components/dirent-list-view/dirent-list-item.js b/frontend/src/components/dirent-list-view/dirent-list-item.js
index f8c10ddaa4..cde51c86bf 100644
--- a/frontend/src/components/dirent-list-view/dirent-list-item.js
+++ b/frontend/src/components/dirent-list-view/dirent-list-item.js
@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import MD5 from 'MD5';
import { UncontrolledTooltip } from 'reactstrap';
-import { gettext, siteRoot, mediaUrl, username, canGenerateShareLink } from '../../utils/constants';
+import { gettext, siteRoot, mediaUrl, username } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import { seafileAPI } from '../../utils/seafile-api';
import URLDecorator from '../../utils/url-decorator';
@@ -411,7 +411,7 @@ class DirentListItem extends React.Component {
dragStartItemData = JSON.parse(dragStartItemData);
if (Array.isArray(dragStartItemData)) { //move items
let direntPaths = dragStartItemData.map(draggedItem => {
- return draggedItem.nodeRootPath
+ return draggedItem.nodeRootPath;
});
let selectedPath = Utils.joinPath(this.props.path, this.props.dirent.name);
@@ -462,7 +462,7 @@ class DirentListItem extends React.Component {
if (currentRepoInfo.permission === 'cloud-edit' || currentRepoInfo.permission === 'preview') {
return '';
}
-
+
return (
{selectedDirentList.length > 1 ?
@@ -470,17 +470,21 @@ class DirentListItem extends React.Component {
{this.state.isOperationShow && !dirent.isSelected &&
- -
-
-
- {showShareBtn &&
- -
-
-
- }
- -
-
-
+ {(dirent.permission === 'rw' || dirent.permission === 'r') && (
+ -
+
+
+ )}
+ {showShareBtn && (
+ -
+
+
+ )}
+ {dirent.permission === 'rw' && (
+ -
+
+
+ )}
-
- -
-
-
- {showShareBtn &&
- -
-
-
- }
- -
-
-
+ {(dirent.permission === 'rw' || dirent.permission === 'r') && (
+ -
+
+
+ )}
+ {showShareBtn && (
+ -
+
+
+ )}
+ {dirent.permission === 'rw' && (
+ -
+
+
+ )}
-
+
);
diff --git a/frontend/src/components/wiki-markdown-viewer.js b/frontend/src/components/wiki-markdown-viewer.js
index 1dfca1aa27..a6bf1b8948 100644
--- a/frontend/src/components/wiki-markdown-viewer.js
+++ b/frontend/src/components/wiki-markdown-viewer.js
@@ -127,21 +127,25 @@ class WikiMarkdownViewer extends React.Component {
changeInlineNode = (item) => {
if (item.object == 'inline') {
- let url;
+ let url, imagePath;
// change image url
if (item.type == 'image' && isPublicWiki) {
url = item.data.src;
const re = new RegExp(serviceURL + '/lib/' + repoID +'/file.*raw=1');
// different repo
- if (!re.test(url)) {
+ if (re.test(url)) {
+ // get image path
+ let index = url.indexOf('/file');
+ let index2 = url.indexOf('?');
+ imagePath = url.substring(index + 5, index2);
+ } else if (/^\.\.\/*/.test(url) || /^\.\/*/.test(url)) {
+ const path = this.props.path;
+ const originalPath = path.slice(0, path.lastIndexOf('/')) + '/' + url;
+ imagePath = Utils.pathNormalize(originalPath);
+ } else {
return;
}
- // get image path
- let index = url.indexOf('/file');
- let index2 = url.indexOf('?');
- const imagePath = url.substring(index + 5, index2);
- // replace url
item.data.src = serviceURL + '/view-image-via-public-wiki/?slug=' + slug + '&path=' + imagePath;
}
diff --git a/frontend/src/css/work-weixin-departments.css b/frontend/src/css/work-weixin-departments.css
index cd0c4a2095..9771bcd857 100644
--- a/frontend/src/css/work-weixin-departments.css
+++ b/frontend/src/css/work-weixin-departments.css
@@ -1,4 +1,10 @@
+.cur-view-content {
+ position: relative;
+}
.dir-content-main {
+ position: absolute;
+ right: 0;
+ height: 100%;
width: 75%;
overflow-y: hidden;
padding-right: 1rem;
@@ -17,13 +23,16 @@
height: 140px;
}
.dir-content-nav {
- width: 24%;
+ position: fixed;
overflow: hidden;
}
.dir-content-nav:hover {
overflow: auto;
}
.dir-content-resize {
+ position: absolute;
+ left: 25%;
+ height: 100%;
width: 1%;
border-left: 1px solid #eee;
}
diff --git a/frontend/src/pages/lib-content-view/lib-content-view.js b/frontend/src/pages/lib-content-view/lib-content-view.js
index e8a5d8fa5f..a02647890e 100644
--- a/frontend/src/pages/lib-content-view/lib-content-view.js
+++ b/frontend/src/pages/lib-content-view/lib-content-view.js
@@ -550,11 +550,11 @@ class LibContentView extends React.Component {
seafileAPI.listDir(repoID, path).then(res => {
let newDirentList = res.data.dirent_list;
let newAddedDirents = newDirentList.filter(item => {
- return !nodeChildrenNames.includes(item.name)
- })
+ return !nodeChildrenNames.includes(item.name);
+ });
newAddedDirents.map(item => {
this.addNodeToTree(item.name, path, item.type);
- })
+ });
});
}
diff --git a/frontend/src/pages/wiki/main-panel.js b/frontend/src/pages/wiki/main-panel.js
index ab9c2127c8..d53a83c9db 100644
--- a/frontend/src/pages/wiki/main-panel.js
+++ b/frontend/src/pages/wiki/main-panel.js
@@ -116,6 +116,7 @@ class MainPanel extends Component {
latestContributor={this.props.latestContributor}
onLinkClick={this.props.onLinkClick}
isWiki={true}
+ path={this.props.path}
/>
)}
{(!this.props.isDataLoading && !this.props.isViewFile) && (
diff --git a/frontend/src/repo-snapshot.js b/frontend/src/repo-snapshot.js
index b0750bfa55..39ad180dc6 100644
--- a/frontend/src/repo-snapshot.js
+++ b/frontend/src/repo-snapshot.js
@@ -1,7 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { navigate } from '@reach/router';
-import moment from 'moment';
import { Utils } from './utils/utils';
import { gettext, loginUrl, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
import { seafileAPI } from './utils/seafile-api';
@@ -233,26 +232,26 @@ class Content extends React.Component {
}
return (
-
-
-
- {this.theadData.map((item, index) => {
- return {item.text} | ;
- })}
-
-
-
- {folderItems.map((item, index) => {
- return ;
- })
- }
-
-
+
+
+
+ {this.theadData.map((item, index) => {
+ return {item.text} | ;
+ })}
+
+
+
+ {folderItems.map((item, index) => {
+ return ;
+ })
+ }
+
+
);
}
}
diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js
index 9a80b81266..e1bc531b7c 100644
--- a/frontend/src/utils/utils.js
+++ b/frontend/src/utils/utils.js
@@ -231,8 +231,8 @@ export const Utils = {
isIEBrower: function() { // is ie <= ie11 not include Edge
var userAgent = navigator.userAgent;
- var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1;
- var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
+ var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;
+ var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
return isIE || isIE11;
},
@@ -880,6 +880,21 @@ export const Utils = {
return password;
},
+ pathNormalize: function(originalPath) {
+ let oldPath = originalPath.split('/');
+ let newPath = [];
+ for (let i = 0; i < oldPath.length; i++) {
+ if (oldPath[i] === '.' || oldPath[i] === '') {
+ continue;
+ } else if (oldPath[i] === '..') {
+ newPath.pop();
+ } else {
+ newPath.push(oldPath[i]);
+ }
+ }
+ return newPath.join('/');
+ },
+
getEventData: function(event, data) {
if (event.target.dataset) {
return event.target.dataset[data];
diff --git a/seahub/api2/views.py b/seahub/api2/views.py
index 891038df71..9c5ea0a18c 100644
--- a/seahub/api2/views.py
+++ b/seahub/api2/views.py
@@ -641,6 +641,7 @@ def repo_download_info(request, repo_id, gen_sync_token=True):
'random_key': random_key,
'repo_version': repo_version,
'head_commit_id': repo.head_cmmt_id,
+ 'permission': seafile_api.check_permission_by_path(repo_id, '/', email)
}
if is_pro_version() and ENABLE_STORAGE_CLASSES: