mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-21 19:37:28 +00:00
Merge branch '7.0'
This commit is contained in:
6
frontend/package-lock.json
generated
6
frontend/package-lock.json
generated
@@ -15904,9 +15904,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"seafile-js": {
|
"seafile-js": {
|
||||||
"version": "0.2.100",
|
"version": "0.2.101",
|
||||||
"resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.100.tgz",
|
"resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.101.tgz",
|
||||||
"integrity": "sha512-QrzO3vMSeL+4NRvb9/sjGdCtYzOIsXI7PhbPZrVmMc8XaXWL9ZzgMqMEGVYUgQlALQChNhXqqyfRLvZ3/WKEUg==",
|
"integrity": "sha512-CqF+4FKnUhnUYKCjiVbp10GkI9Ej+d4UfaWRvdGNaR74tK+0D9dUq7RNXUGS/MpIAlif7hbz5k+LUFafkfGmNg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"form-data": "^2.3.2",
|
"form-data": "^2.3.2",
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
"react-responsive": "^6.1.1",
|
"react-responsive": "^6.1.1",
|
||||||
"react-select": "^2.4.1",
|
"react-select": "^2.4.1",
|
||||||
"reactstrap": "^6.4.0",
|
"reactstrap": "^6.4.0",
|
||||||
"seafile-js": "^0.2.100",
|
"seafile-js": "^0.2.101",
|
||||||
"socket.io-client": "^2.2.0",
|
"socket.io-client": "^2.2.0",
|
||||||
"sw-precache-webpack-plugin": "0.11.4",
|
"sw-precache-webpack-plugin": "0.11.4",
|
||||||
"unified": "^7.0.0",
|
"unified": "^7.0.0",
|
||||||
|
@@ -391,24 +391,24 @@ class GenerateShareLink extends React.Component {
|
|||||||
</Label>
|
</Label>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup check className="permission">
|
<FormGroup check className="permission">
|
||||||
<Label check>
|
<Label className="form-check-label">
|
||||||
<Input type="radio" name="radio1" defaultChecked={true} onChange={() => this.setPermission('previewAndDownload')}/>{' '}{gettext('Preview and download')}
|
<Input type="radio" name="radio1" defaultChecked={true} onChange={() => this.setPermission('previewAndDownload')}/>{' '}{gettext('Preview and download')}
|
||||||
</Label>
|
</Label>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup check className="permission">
|
<FormGroup check className="permission">
|
||||||
<Label>
|
<Label className="form-check-label">
|
||||||
<Input type="radio" name="radio1" onChange={() => this.setPermission('preview')} />{' '}{gettext('Preview only')}
|
<Input type="radio" name="radio1" onChange={() => this.setPermission('preview')} />{' '}{gettext('Preview only')}
|
||||||
</Label>
|
</Label>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
{(Utils.isOfficeFile(this.props.itemPath) && fileInfo && fileInfo.can_edit) &&
|
{(Utils.isOfficeFile(this.props.itemPath) && fileInfo && fileInfo.can_edit) &&
|
||||||
<FormGroup check className="permission">
|
<FormGroup check className="permission">
|
||||||
<Label>
|
<Label className="form-check-label">
|
||||||
<Input type="radio" name="radio1" onChange={() => this.setPermission('editOnCloudAndDownload')} />{' '}{gettext('Edit on cloud and download')}
|
<Input type="radio" name="radio1" onChange={() => this.setPermission('editOnCloudAndDownload')} />{' '}{gettext('Edit on cloud and download')}
|
||||||
</Label>
|
</Label>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
}
|
}
|
||||||
{this.state.errorInfo && <Alert color="danger" className="mt-2">{gettext(this.state.errorInfo)}</Alert>}
|
{this.state.errorInfo && <Alert color="danger" className="mt-2">{gettext(this.state.errorInfo)}</Alert>}
|
||||||
<Button onClick={this.generateShareLink}>{gettext('Generate')}</Button>
|
<Button onClick={this.generateShareLink} className="mt-2">{gettext('Generate')}</Button>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -79,6 +79,7 @@ class DirGridView extends React.Component {
|
|||||||
isDirentDetailShow={this.props.isDirentDetailShow}
|
isDirentDetailShow={this.props.isDirentDetailShow}
|
||||||
onItemRename={this.props.onItemRename}
|
onItemRename={this.props.onItemRename}
|
||||||
onAddFolder={this.props.onAddFolder}
|
onAddFolder={this.props.onAddFolder}
|
||||||
|
onFileTagChanged={this.props.onFileTagChanged}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import MD5 from 'MD5';
|
||||||
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
import { gettext, siteRoot, mediaUrl } from '../../utils/constants';
|
import { gettext, siteRoot, mediaUrl } from '../../utils/constants';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
|
|
||||||
@@ -136,6 +138,13 @@ class DirentGridItem extends React.Component {
|
|||||||
let iconUrl = Utils.getDirentIcon(dirent, true);
|
let iconUrl = Utils.getDirentIcon(dirent, true);
|
||||||
let fileUrl = dirent.encoded_thumbnail_src ? this.getFileUrl(dirent.encoded_thumbnail_src) : '';
|
let fileUrl = dirent.encoded_thumbnail_src ? this.getFileUrl(dirent.encoded_thumbnail_src) : '';
|
||||||
|
|
||||||
|
let toolTipID = '';
|
||||||
|
let tagTitle = '';
|
||||||
|
if (dirent.file_tags && dirent.file_tags.length > 0) {
|
||||||
|
toolTipID = MD5(dirent.name).slice(0, 7);
|
||||||
|
tagTitle = dirent.file_tags.map(item => item.name).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
let dirHref = '';
|
let dirHref = '';
|
||||||
if (this.props.currentRepoInfo) {
|
if (this.props.currentRepoInfo) {
|
||||||
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
|
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
|
||||||
@@ -169,6 +178,21 @@ class DirentGridItem extends React.Component {
|
|||||||
{dirent.is_locked && <img className="grid-file-locked-icon" src={mediaUrl + 'img/file-locked-32.png'} alt={gettext('locked')} title={lockedInfo}/>}
|
{dirent.is_locked && <img className="grid-file-locked-icon" src={mediaUrl + 'img/file-locked-32.png'} alt={gettext('locked')} title={lockedInfo}/>}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-file-name" onDragStart={this.onGridItemDragStart} draggable="true" >
|
<div className="grid-file-name" onDragStart={this.onGridItemDragStart} draggable="true" >
|
||||||
|
{(dirent.type !== 'dir' && dirent.file_tags && dirent.file_tags.length > 0) && (
|
||||||
|
<Fragment>
|
||||||
|
<div id={`tag-list-title-${toolTipID}`} className="dirent-item tag-list tag-list-stacked d-inline-block align-middle">
|
||||||
|
{dirent.file_tags.map((fileTag, index) => {
|
||||||
|
let length = dirent.file_tags.length;
|
||||||
|
return (
|
||||||
|
<span className="file-tag" key={fileTag.id} style={{zIndex:length - index, backgroundColor:fileTag.color}}></span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<UncontrolledTooltip target={`tag-list-title-${toolTipID}`} placement="bottom">
|
||||||
|
{tagTitle}
|
||||||
|
</UncontrolledTooltip>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
<a className={`grid-file-name-link ${this.state.isGridSelected ? 'grid-link-selected-active' : ''}`} href={dirent.type === 'dir' ? dirHref : fileHref} onClick={this.onItemLinkClick}>{dirent.name}</a>
|
<a className={`grid-file-name-link ${this.state.isGridSelected ? 'grid-link-selected-active' : ''}`} href={dirent.type === 'dir' ? dirHref : fileHref} onClick={this.onItemLinkClick}>{dirent.name}</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@@ -15,6 +15,7 @@ import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
|||||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||||
import ShareDialog from '../dialog/share-dialog';
|
import ShareDialog from '../dialog/share-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
||||||
|
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||||
import Rename from '../../components/dialog/rename-grid-item-dialog';
|
import Rename from '../../components/dialog/rename-grid-item-dialog';
|
||||||
import CreateFile from '../dialog/create-file-dialog';
|
import CreateFile from '../dialog/create-file-dialog';
|
||||||
import CreateFolder from '../dialog/create-folder-dialog';
|
import CreateFolder from '../dialog/create-folder-dialog';
|
||||||
@@ -40,6 +41,7 @@ const propTypes = {
|
|||||||
updateDirent: PropTypes.func.isRequired,
|
updateDirent: PropTypes.func.isRequired,
|
||||||
isDirentDetailShow: PropTypes.bool.isRequired,
|
isDirentDetailShow: PropTypes.bool.isRequired,
|
||||||
onGridItemClick: PropTypes.func,
|
onGridItemClick: PropTypes.func,
|
||||||
|
onFileTagChanged: PropTypes.func,
|
||||||
onAddFolder: PropTypes.func.isRequired,
|
onAddFolder: PropTypes.func.isRequired,
|
||||||
showDirentDetail: PropTypes.func.isRequired,
|
showDirentDetail: PropTypes.func.isRequired,
|
||||||
onItemRename: PropTypes.func.isRequired,
|
onItemRename: PropTypes.func.isRequired,
|
||||||
@@ -56,6 +58,7 @@ class DirentGridView extends React.Component{
|
|||||||
isShareDialogShow: false,
|
isShareDialogShow: false,
|
||||||
isMoveDialogShow: false,
|
isMoveDialogShow: false,
|
||||||
isCopyDialogShow: false,
|
isCopyDialogShow: false,
|
||||||
|
isEditFileTagShow: false,
|
||||||
isZipDialogOpen: false,
|
isZipDialogOpen: false,
|
||||||
isRenameDialogShow: false,
|
isRenameDialogShow: false,
|
||||||
isCreateFolderDialogShow: false,
|
isCreateFolderDialogShow: false,
|
||||||
@@ -133,6 +136,9 @@ class DirentGridView extends React.Component{
|
|||||||
case 'Copy':
|
case 'Copy':
|
||||||
this.onItemCopyToggle();
|
this.onItemCopyToggle();
|
||||||
break;
|
break;
|
||||||
|
case 'Tags':
|
||||||
|
this.onEditFileTagToggle();
|
||||||
|
break;
|
||||||
case 'Permission':
|
case 'Permission':
|
||||||
this.onPermissionItem();
|
this.onPermissionItem();
|
||||||
break;
|
break;
|
||||||
@@ -165,6 +171,18 @@ class DirentGridView extends React.Component{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEditFileTagToggle = () => {
|
||||||
|
this.setState({
|
||||||
|
isEditFileTagShow: !this.state.isEditFileTagShow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileTagChanged = () => {
|
||||||
|
let dirent = this.state.activeDirent ? this.state.activeDirent : '';
|
||||||
|
let direntPath = Utils.joinPath(this.props.path, dirent.name);
|
||||||
|
this.props.onFileTagChanged(dirent, direntPath);
|
||||||
|
}
|
||||||
|
|
||||||
getDirentPath = (dirent) => {
|
getDirentPath = (dirent) => {
|
||||||
let path = this.props.path;
|
let path = this.props.path;
|
||||||
return path === '/' ? path + dirent.name : path + '/' + dirent.name;
|
return path === '/' ? path + dirent.name : path + '/' + dirent.name;
|
||||||
@@ -437,7 +455,7 @@ class DirentGridView extends React.Component{
|
|||||||
contextmenuList = contextmenuList.length > 0 ? [...contextmenuList, 'Divider'] : [];
|
contextmenuList = contextmenuList.length > 0 ? [...contextmenuList, 'Divider'] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let { RENAME, MOVE, COPY, PERMISSION, OPEN_VIA_CLIENT, LOCK, UNLOCK, COMMENT, HISTORY, ACCESS_LOG } = TextTranslation;
|
let { RENAME, MOVE, COPY, PERMISSION, OPEN_VIA_CLIENT, LOCK, UNLOCK, COMMENT, HISTORY, ACCESS_LOG, TAGS } = TextTranslation;
|
||||||
if (type === 'dir' && permission === 'rw') {
|
if (type === 'dir' && permission === 'rw') {
|
||||||
if (can_set_folder_perm) {
|
if (can_set_folder_perm) {
|
||||||
menuList = [...contextmenuList, RENAME, MOVE, COPY, 'Divider', PERMISSION, 'Divider', OPEN_VIA_CLIENT];
|
menuList = [...contextmenuList, RENAME, MOVE, COPY, 'Divider', PERMISSION, 'Divider', OPEN_VIA_CLIENT];
|
||||||
@@ -460,6 +478,7 @@ class DirentGridView extends React.Component{
|
|||||||
menuList.push(MOVE);
|
menuList.push(MOVE);
|
||||||
}
|
}
|
||||||
menuList.push(COPY);
|
menuList.push(COPY);
|
||||||
|
menuList.push(TAGS);
|
||||||
if (isPro) {
|
if (isPro) {
|
||||||
if (dirent.is_locked) {
|
if (dirent.is_locked) {
|
||||||
if (dirent.locked_by_me || (dirent.lock_owner === 'OnlineOffice' && permission === 'rw')) {
|
if (dirent.locked_by_me || (dirent.lock_owner === 'OnlineOffice' && permission === 'rw')) {
|
||||||
@@ -590,6 +609,15 @@ class DirentGridView extends React.Component{
|
|||||||
dirent={this.state.activeDirent}
|
dirent={this.state.activeDirent}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
{this.state.isEditFileTagShow &&
|
||||||
|
<EditFileTagDialog
|
||||||
|
repoID={this.props.repoID}
|
||||||
|
fileTagList={dirent.file_tags}
|
||||||
|
filePath={direntPath}
|
||||||
|
toggleCancel={this.onEditFileTagToggle}
|
||||||
|
onFileTagChanged={this.onFileTagChanged}
|
||||||
|
/>
|
||||||
|
}
|
||||||
{this.state.isShareDialogShow &&
|
{this.state.isShareDialogShow &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<ShareDialog
|
<ShareDialog
|
||||||
|
@@ -555,12 +555,12 @@ class DirentListItem extends React.Component {
|
|||||||
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
|
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
|
||||||
}
|
}
|
||||||
let fileHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(direntPath);
|
let fileHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(direntPath);
|
||||||
let toolTipID = MD5(dirent.name).slice(0, 7);
|
|
||||||
|
let toolTipID = '';
|
||||||
let tagTitle = '';
|
let tagTitle = '';
|
||||||
if (dirent.file_tags && dirent.file_tags.length > 0) {
|
if (dirent.file_tags && dirent.file_tags.length > 0) {
|
||||||
dirent.file_tags.forEach(item => {
|
toolTipID = MD5(dirent.name).slice(0, 7);
|
||||||
tagTitle += item.name + ' ';
|
tagTitle = dirent.file_tags.map(item => item.name).join(' ');
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconUrl = Utils.getDirentIcon(dirent);
|
let iconUrl = Utils.getDirentIcon(dirent);
|
||||||
@@ -613,7 +613,7 @@ class DirentListItem extends React.Component {
|
|||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td className="tag-list-title">
|
<td className="tag-list-title">
|
||||||
{(dirent.type !== 'dir' && dirent.file_tags) && (
|
{(dirent.type !== 'dir' && dirent.file_tags && dirent.file_tags.length > 0) && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div id={`tag-list-title-${toolTipID}`} className="dirent-item tag-list tag-list-stacked">
|
<div id={`tag-list-title-${toolTipID}`} className="dirent-item tag-list tag-list-stacked">
|
||||||
{dirent.file_tags.map((fileTag, index) => {
|
{dirent.file_tags.map((fileTag, index) => {
|
||||||
|
@@ -35,11 +35,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.grid-file-img-link .thumbnail {
|
.grid-file-img-link .thumbnail {
|
||||||
max-width: 96px;
|
max-width: 88px;
|
||||||
max-height: 96px;
|
max-height: 88px;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
|
background: #fff;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 3px;
|
border-radius: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-file-img-link::before {
|
.grid-file-img-link::before {
|
||||||
|
@@ -11,9 +11,9 @@
|
|||||||
config: {
|
config: {
|
||||||
draftID: '{{ draft_id }}',
|
draftID: '{{ draft_id }}',
|
||||||
draftRepoID: '{{ draft_repo_id }}',
|
draftRepoID: '{{ draft_repo_id }}',
|
||||||
draftFilePath: '{{ draft_file_path }}',
|
draftFilePath: '{{ draft_file_path|escapejs }}',
|
||||||
draftOriginFilePath: '{{ draft_origin_file_path }}',
|
draftOriginFilePath: '{{ draft_origin_file_path|escapejs }}',
|
||||||
draftFileName: '{{ draft_file_name }}',
|
draftFileName: '{{ draft_file_name|escapejs }}',
|
||||||
perm: '{{ permission }}',
|
perm: '{{ permission }}',
|
||||||
author: '{{ author }}',
|
author: '{{ author }}',
|
||||||
authorAvatar: '{{ author_avatar_url }}',
|
authorAvatar: '{{ author_avatar_url }}',
|
||||||
|
Reference in New Issue
Block a user