mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
feat: draft due to github connect
This commit is contained in:
@@ -9,6 +9,7 @@ const entryFiles = {
|
|||||||
fileHistory: "/file-history.js",
|
fileHistory: "/file-history.js",
|
||||||
fileHistoryOld: "/file-history-old.js",
|
fileHistoryOld: "/file-history-old.js",
|
||||||
sdocFileHistory: "/pages/sdoc-file-history/index.js",
|
sdocFileHistory: "/pages/sdoc-file-history/index.js",
|
||||||
|
sdocRevision: "/pages/sdoc-revision/index.js",
|
||||||
app: "/app.js",
|
app: "/app.js",
|
||||||
draft: "/draft.js",
|
draft: "/draft.js",
|
||||||
sharedDirView: "/shared-dir-view.js",
|
sharedDirView: "/shared-dir-view.js",
|
||||||
|
51
frontend/src/css/sdoc-revision.css
Normal file
51
frontend/src/css/sdoc-revision.css
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
.sdoc-revision .sdoc-revision-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-header {
|
||||||
|
height: 50px;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-header .sdoc-revision-header-left {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-header .file-name {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-header .sdoc-revision-header-right {
|
||||||
|
height: 100%;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-content {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
padding: 20px 40px;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-content .sdoc-revision-viewer {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 120px;
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
word-break: break-word;
|
||||||
|
border: 1px solid #e6e6dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-content .sdoc-editor-content {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sdoc-revision .sdoc-revision-content .article {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
124
frontend/src/pages/sdoc-revision/index.js
Normal file
124
frontend/src/pages/sdoc-revision/index.js
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDom from 'react-dom';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { Button } from 'reactstrap';
|
||||||
|
import { DiffViewer } from '@seafile/sdoc-editor';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
import Loading from '../../components/loading';
|
||||||
|
import GoBack from '../../components/common/go-back';
|
||||||
|
import { Utils } from '../../utils/utils';
|
||||||
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
|
|
||||||
|
import '../../css/layout.css';
|
||||||
|
import '../../css/sdoc-revision.css';
|
||||||
|
|
||||||
|
const { serviceURL, avatarURL, siteRoot } = window.app.config;
|
||||||
|
const { username, name } = window.app.pageOptions;
|
||||||
|
const { repoID, fileName, filePath, docUuid, assetsUrl, fileDownloadLink, originFileDownloadLink, isPublished } = window.sdocRevision;
|
||||||
|
|
||||||
|
window.seafile = {
|
||||||
|
repoID,
|
||||||
|
docPath: filePath,
|
||||||
|
docName: fileName,
|
||||||
|
docUuid,
|
||||||
|
isOpenSocket: false,
|
||||||
|
serviceUrl: serviceURL,
|
||||||
|
name,
|
||||||
|
username,
|
||||||
|
avatarURL,
|
||||||
|
siteRoot,
|
||||||
|
assetsUrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
class SdocRevision extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isLoading: true,
|
||||||
|
errorMessage: '',
|
||||||
|
revisionContent: '',
|
||||||
|
originContent: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
fetch(fileDownloadLink).then(res => {
|
||||||
|
return res.json();
|
||||||
|
}).then(revisionContent => {
|
||||||
|
fetch(originFileDownloadLink).then(res => {
|
||||||
|
return res.json();
|
||||||
|
}).then(originContent => {
|
||||||
|
this.setState({ revisionContent, originContent, isLoading: false, errorMessage: '' });
|
||||||
|
}).catch(error => {
|
||||||
|
const errorMessage = Utils.getErrorMsg(error, true);
|
||||||
|
this.setState({ isLoading: false, errorMessage });
|
||||||
|
});
|
||||||
|
}).catch(error => {
|
||||||
|
const errorMessage = Utils.getErrorMsg(error, true);
|
||||||
|
this.setState({ isLoading: false, errorMessage });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
publishRevision = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
|
seafileAPI.sdocPublishRevision(docUuid).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContent = () => {
|
||||||
|
const { isLoading, errorMessage, revisionContent, originContent } = this.state;
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className="sdoc-revision-viewer d-flex align-items-center justify-content-center">
|
||||||
|
<Loading />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage) {
|
||||||
|
return (
|
||||||
|
<div className="sdoc-revision-viewer d-flex align-items-center justify-content-center">
|
||||||
|
{gettext(errorMessage)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DiffViewer
|
||||||
|
currentContent={revisionContent}
|
||||||
|
lastContent={originContent}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="sdoc-revision d-flex h-100 w-100 o-hidden">
|
||||||
|
<div className="sdoc-revision-container d-flex flex-column">
|
||||||
|
<div className="sdoc-revision-header pt-2 pb-2 pl-4 pr-4 d-flex justify-content-between w-100 o-hidden">
|
||||||
|
<div className={classnames('sdoc-revision-header-left d-flex align-items-center o-hidden')}>
|
||||||
|
<GoBack />
|
||||||
|
<div className="file-name text-truncate">{fileName}</div>
|
||||||
|
</div>
|
||||||
|
<div className="sdoc-revision-header-right">
|
||||||
|
<Button color="success"></Button>
|
||||||
|
{!isPublished && (
|
||||||
|
<Button color="success" onClick={this.publishRevision}>{gettext('Publish')}</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sdoc-revision-content f-flex">
|
||||||
|
{this.renderContent()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDom.render(<SdocRevision />, document.getElementById('wrapper'));
|
@@ -1543,6 +1543,11 @@ export const Utils = {
|
|||||||
generateHistoryURL: function(siteRoot, repoID, path) {
|
generateHistoryURL: function(siteRoot, repoID, path) {
|
||||||
if (!siteRoot || !repoID || !path) return '';
|
if (!siteRoot || !repoID || !path) return '';
|
||||||
return siteRoot + 'repo/file_revisions/' + repoID + '/?p=' + this.encodePath(path);
|
return siteRoot + 'repo/file_revisions/' + repoID + '/?p=' + this.encodePath(path);
|
||||||
|
},
|
||||||
|
|
||||||
|
generateRevisionURL: function(siteRoot, repoID, path) {
|
||||||
|
if (!siteRoot || !repoID || !path) return '';
|
||||||
|
return siteRoot + 'repo/sdoc_revision/' + repoID + '/?p=' + this.encodePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -10,7 +10,7 @@ const { serviceURL, avatarURL, siteRoot } = window.app.config;
|
|||||||
const { username, name } = window.app.userInfo;
|
const { username, name } = window.app.userInfo;
|
||||||
const {
|
const {
|
||||||
repoID, repoName, parentDir, filePerm,
|
repoID, repoName, parentDir, filePerm,
|
||||||
docPath, docName, docUuid, seadocAccessToken, seadocServerUrl, assetsUrl
|
docPath, docName, docUuid, seadocAccessToken, seadocServerUrl, assetsUrl,
|
||||||
} = window.app.pageOptions;
|
} = window.app.pageOptions;
|
||||||
|
|
||||||
window.seafile = {
|
window.seafile = {
|
||||||
@@ -31,7 +31,8 @@ window.seafile = {
|
|||||||
parentFolderURL: `${siteRoot}library/${repoID}/${Utils.encodePath(repoName + parentDir)}`,
|
parentFolderURL: `${siteRoot}library/${repoID}/${Utils.encodePath(repoName + parentDir)}`,
|
||||||
assetsUrl,
|
assetsUrl,
|
||||||
isShowInternalLink: true,
|
isShowInternalLink: true,
|
||||||
isStarIconShown: true // for star/unstar
|
isStarIconShown: true, // for star/unstar
|
||||||
|
revisionURL: Utils.generateRevisionURL(siteRoot, repoID, docPath),
|
||||||
};
|
};
|
||||||
|
|
||||||
ReactDom.render(
|
ReactDom.render(
|
||||||
|
@@ -3,6 +3,8 @@ from .apis import SeadocAccessToken, SeadocUploadLink, SeadocDownloadLink, Seado
|
|||||||
SeadocUploadImage, SeadocDownloadImage, SeadocCopyHistoryFile, SeadocHistory, SeadocDrafts, SeadocMaskAsDraft, \
|
SeadocUploadImage, SeadocDownloadImage, SeadocCopyHistoryFile, SeadocHistory, SeadocDrafts, SeadocMaskAsDraft, \
|
||||||
SeadocCommentsView, SeadocCommentView, SeadocRevisions, SeadocPublishRevision
|
SeadocCommentsView, SeadocCommentView, SeadocRevisions, SeadocPublishRevision
|
||||||
|
|
||||||
|
from .views import sdoc_revision
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r'^access-token/(?P<repo_id>[-0-9a-f]{36})/$', SeadocAccessToken.as_view(), name='seadoc_access_token'),
|
re_path(r'^access-token/(?P<repo_id>[-0-9a-f]{36})/$', SeadocAccessToken.as_view(), name='seadoc_access_token'),
|
||||||
re_path(r'^upload-file/(?P<file_uuid>[-0-9a-f]{36})/$', SeadocUploadFile.as_view(), name='seadoc_upload_file'),
|
re_path(r'^upload-file/(?P<file_uuid>[-0-9a-f]{36})/$', SeadocUploadFile.as_view(), name='seadoc_upload_file'),
|
||||||
|
65
seahub/seadoc/views.py
Normal file
65
seahub/seadoc/views.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import os
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
from seaserv import get_repo
|
||||||
|
from seahub.auth.decorators import login_required
|
||||||
|
from seahub.utils import render_error
|
||||||
|
from seahub.views import check_folder_permission, validate_owner, get_seadoc_file_uuid
|
||||||
|
from seahub.tags.models import FileUUIDMap
|
||||||
|
|
||||||
|
from .utils import is_seadoc_revision, get_seadoc_download_link
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def sdoc_revision(request, repo_id):
|
||||||
|
"""List file revisions in file version history page.
|
||||||
|
"""
|
||||||
|
repo = get_repo(repo_id)
|
||||||
|
if not repo:
|
||||||
|
error_msg = _("Library does not exist")
|
||||||
|
return render_error(request, error_msg)
|
||||||
|
|
||||||
|
# perm check
|
||||||
|
if not check_folder_permission(request, repo_id, '/'):
|
||||||
|
error_msg = _("Permission denied.")
|
||||||
|
return render_error(request, error_msg)
|
||||||
|
|
||||||
|
path = request.GET.get('p', '/')
|
||||||
|
if not path:
|
||||||
|
return render_error(request)
|
||||||
|
|
||||||
|
if path[-1] == '/':
|
||||||
|
path = path[:-1]
|
||||||
|
|
||||||
|
u_filename = os.path.basename(path)
|
||||||
|
|
||||||
|
# Check whether user is repo owner
|
||||||
|
if validate_owner(request, repo_id):
|
||||||
|
is_owner = True
|
||||||
|
else:
|
||||||
|
is_owner = False
|
||||||
|
|
||||||
|
file_uuid = get_seadoc_file_uuid(repo, path)
|
||||||
|
uuid_map = FileUUIDMap.objects.get_fileuuidmap_by_uuid(file_uuid)
|
||||||
|
return_dict = {
|
||||||
|
'repo': repo,
|
||||||
|
'path': path,
|
||||||
|
'u_filename': u_filename,
|
||||||
|
'file_uuid': file_uuid,
|
||||||
|
'is_owner': is_owner,
|
||||||
|
'can_compare': True,
|
||||||
|
'assets_url': '/api/v2.1/seadoc/download-image/' + file_uuid,
|
||||||
|
'file_download_link': get_seadoc_download_link(uuid_map)
|
||||||
|
}
|
||||||
|
|
||||||
|
revision_info = is_seadoc_revision(file_uuid)
|
||||||
|
return_dict.update(revision_info)
|
||||||
|
|
||||||
|
origin_doc_uuid = return_dict.get('origin_doc_uuid', '')
|
||||||
|
is_published = return_dict.get('is_published', False)
|
||||||
|
if (origin_doc_uuid and not is_published):
|
||||||
|
uuid_map = FileUUIDMap.objects.get_fileuuidmap_by_uuid(origin_doc_uuid)
|
||||||
|
return_dict['origin_file_download_link'] = get_seadoc_download_link(uuid_map)
|
||||||
|
|
||||||
|
return render(request, 'sdoc_revision.html', return_dict)
|
||||||
|
|
37
seahub/templates/sdoc_revision.html
Normal file
37
seahub/templates/sdoc_revision.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{% extends "base_for_react.html" %}
|
||||||
|
{% load render_bundle from webpack_loader %}
|
||||||
|
|
||||||
|
{% block extra_style %}
|
||||||
|
{% render_bundle 'sdocRevision' 'css'%}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_script %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.app.config.lang = '{{LANGUAGE_CODE}}';
|
||||||
|
window.sdocRevision = {
|
||||||
|
repoID: '{{ repo.id }}',
|
||||||
|
repoName: '{{ repo.name }}',
|
||||||
|
filePath: '{{ path|escapejs }}',
|
||||||
|
fileName: '{{ u_filename|escapejs }}',
|
||||||
|
docUuid: '{{ file_uuid }}',
|
||||||
|
domain: '{{ domain }}',
|
||||||
|
protocol: '{{ protocol }}',
|
||||||
|
assetsUrl: '{{ assets_url }}',
|
||||||
|
fileDownloadLink: '{{ file_download_link }}',
|
||||||
|
isSdocRevision: {% if is_sdoc_revision %}true{% else %}false{% endif %},
|
||||||
|
originDocUuid: '{{ origin_doc_uuid }}',
|
||||||
|
originFileDownloadLink: '{{ origin_file_download_link }}',
|
||||||
|
originParentPath: '{{ origin_parent_path }}',
|
||||||
|
originFilename: '{{ origin_filename }}',
|
||||||
|
originFilePath: '{{ origin_file_path }}',
|
||||||
|
originFileVersion: '{{ origin_file_version }}',
|
||||||
|
publishFileVersion: '{{ publish_file_version }}',
|
||||||
|
publisher: '{{ publisher }}',
|
||||||
|
publisherNickname: '{{ publisher_nickname }}',
|
||||||
|
isPublished: {% if is_published %}true{% else %}false{% endif %},
|
||||||
|
revisionCreatedAt: '{{ revision_created_at }}',
|
||||||
|
revisionUpdatedAt: '{{ revision_updated_at }}',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% render_bundle 'sdocRevision' 'js'%}
|
||||||
|
{% endblock %}
|
@@ -194,6 +194,7 @@ from seahub.api2.endpoints.admin.virus_scan_records import AdminVirusFilesView,
|
|||||||
from seahub.api2.endpoints.file_participants import FileParticipantsView, FileParticipantView
|
from seahub.api2.endpoints.file_participants import FileParticipantsView, FileParticipantView
|
||||||
from seahub.api2.endpoints.repo_related_users import RepoRelatedUsersView
|
from seahub.api2.endpoints.repo_related_users import RepoRelatedUsersView
|
||||||
from seahub.api2.endpoints.repo_auto_delete import RepoAutoDeleteView
|
from seahub.api2.endpoints.repo_auto_delete import RepoAutoDeleteView
|
||||||
|
from seahub.seadoc.views import sdoc_revision
|
||||||
|
|
||||||
from seahub.ocm.settings import OCM_ENDPOINT
|
from seahub.ocm.settings import OCM_ENDPOINT
|
||||||
|
|
||||||
@@ -220,6 +221,7 @@ urlpatterns = [
|
|||||||
path('repo/upload_check/', validate_filename),
|
path('repo/upload_check/', validate_filename),
|
||||||
re_path(r'^repo/download_dir/(?P<repo_id>[-0-9a-f]{36})/$', repo_download_dir, name='repo_download_dir'),
|
re_path(r'^repo/download_dir/(?P<repo_id>[-0-9a-f]{36})/$', repo_download_dir, name='repo_download_dir'),
|
||||||
re_path(r'^repo/file_revisions/(?P<repo_id>[-0-9a-f]{36})/$', file_revisions, name='file_revisions'),
|
re_path(r'^repo/file_revisions/(?P<repo_id>[-0-9a-f]{36})/$', file_revisions, name='file_revisions'),
|
||||||
|
re_path(r'^repo/sdoc_revision/(?P<repo_id>[-0-9a-f]{36})/$', sdoc_revision, name='sdoc_revision'),
|
||||||
re_path(r'^repo/file-access/(?P<repo_id>[-0-9a-f]{36})/$', file_access, name='file_access'),
|
re_path(r'^repo/file-access/(?P<repo_id>[-0-9a-f]{36})/$', file_access, name='file_access'),
|
||||||
re_path(r'^repo/text_diff/(?P<repo_id>[-0-9a-f]{36})/$', text_diff, name='text_diff'),
|
re_path(r'^repo/text_diff/(?P<repo_id>[-0-9a-f]{36})/$', text_diff, name='text_diff'),
|
||||||
re_path(r'^repo/history/(?P<repo_id>[-0-9a-f]{36})/$', repo_history, name='repo_history'),
|
re_path(r'^repo/history/(?P<repo_id>[-0-9a-f]{36})/$', repo_history, name='repo_history'),
|
||||||
|
Reference in New Issue
Block a user