1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-16 23:29:49 +00:00

[draft] removed related code & files (#5993)

* [draft] removed related code & files

* [draft] removed related code & files
This commit is contained in:
llj
2024-03-25 17:22:01 +08:00
committed by GitHub
parent 43f66cbbca
commit 4375115548
43 changed files with 29 additions and 1405 deletions

View File

@@ -3,18 +3,15 @@ import ReactDom from 'react-dom';
import { Router, navigate } from '@gatsbyjs/reach-router';
import MediaQuery from 'react-responsive';
import { Modal } from 'reactstrap';
import { siteRoot, canAddRepo, isDocs } from './utils/constants';
import { siteRoot, canAddRepo } from './utils/constants';
import { Utils } from './utils/utils';
import SystemNotification from './components/system-notification';
import SidePanel from './components/side-panel';
import MainPanel from './components/main-panel';
import DraftsView from './pages/drafts/drafts-view';
import DraftContent from './pages/drafts/draft-content';
import FilesActivities from './pages/dashboard/files-activities';
import MyFileActivities from './pages/dashboard/my-file-activities';
import Starred from './pages/starred/starred';
import LinkedDevices from './pages/linked-devices/linked-devices';
import editUtilities from './utils/editor-utilities';
import ShareAdminLibraries from './pages/share-admin/libraries';
import ShareAdminFolders from './pages/share-admin/folders';
import ShareAdminShareLinks from './pages/share-admin/share-links';
@@ -39,7 +36,6 @@ import './css/search.css';
const FilesActivitiesWrapper = MainContentWrapper(FilesActivities);
const MyFileActivitiesWrapper = MainContentWrapper(MyFileActivities);
const DraftsViewWrapper = MainContentWrapper(DraftsView);
const StarredWrapper = MainContentWrapper(Starred);
const LinkedDevicesWrapper = MainContentWrapper(LinkedDevices);
const SharedLibrariesWrapper = MainContentWrapper(SharedLibraries);
@@ -55,9 +51,6 @@ class App extends Component {
this.state = {
isOpen: false,
isSidePanelClosed: false,
draftCounts: 0,
draftList:[],
isLoadingDraft: true,
currentTab: '/',
pathPrefix: [],
};
@@ -94,33 +87,11 @@ class App extends Component {
// navigate to library page http://127.0.0.1:8000/library/34e7fb92-e91d-499d-bcde-c30ea8af9828/
this.navigateClientUrlToLib();
// e.g. from http://127.0.0.1:8000/drafts/reviews/
// get reviews
// TODO: need refactor later
let href = window.location.href.split('/');
if (isDocs) {
this.getDrafts();
}
this.setState({currentTab: href[href.length - 2]});
}
getDrafts = () => {
editUtilities.listDrafts().then(res => {
this.setState({
draftCounts: res.data.draft_counts,
draftList: res.data.data,
isLoadingDraft: false,
});
});
};
updateDraftsList = (draft_id) => {
this.setState({
draftCounts: this.state.draftCounts - 1,
draftList: this.state.draftList.filter(draft => draft.id != draft_id),
});
};
onCloseSidePanel = () => {
this.setState({
isSidePanelClosed: !this.state.isSidePanelClosed
@@ -238,24 +209,12 @@ class App extends Component {
<React.Fragment>
<SystemNotification />
<div id="main">
<SidePanel isSidePanelClosed={this.state.isSidePanelClosed} onCloseSidePanel={this.onCloseSidePanel} currentTab={currentTab} tabItemClick={this.tabItemClick} draftCounts={this.state.draftCounts} />
<SidePanel isSidePanelClosed={this.state.isSidePanelClosed} onCloseSidePanel={this.onCloseSidePanel} currentTab={currentTab} tabItemClick={this.tabItemClick} />
<MainPanel>
<Router className="reach-router">
{home}
<FilesActivitiesWrapper path={siteRoot + 'dashboard'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<MyFileActivitiesWrapper path={siteRoot + 'my-activities'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<DraftsViewWrapper path={siteRoot + 'drafts'}
onShowSidePanel={this.onShowSidePanel}
onSearchedClick={this.onSearchedClick}
>
<DraftContent
path='/'
getDrafts={this.getDrafts}
isLoadingDraft={this.state.isLoadingDraft}
draftList={this.state.draftList}
updateDraftsList={this.updateDraftsList}
/>
</DraftsViewWrapper>
<StarredWrapper path={siteRoot + 'starred'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<LinkedDevicesWrapper path={siteRoot + 'linked-devices'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<ShareAdminLibrariesWrapper path={siteRoot + 'share-admin-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />

View File

@@ -15,7 +15,6 @@ const MSG_TYPE_REPO_SHARE = 'repo_share';
const MSG_TYPE_REPO_SHARE_TO_GROUP = 'repo_share_to_group';
const MSG_TYPE_REPO_TRANSFER = 'repo_transfer';
const MSG_TYPE_FILE_UPLOADED = 'file_uploaded';
const MSG_TYPE_DRAFT_REVIEWER = 'draft_reviewer';
// const MSG_TYPE_GUEST_INVITATION_ACCEPTED = 'guest_invitation_accepted';
const MSG_TYPE_REPO_MONITOR = 'repo_monitor';
const MSG_TYPE_DELETED_FILES = 'deleted_files';
@@ -222,22 +221,6 @@ class NoticeItem extends React.Component {
return {avatar_url, notice};
}
if (noticeType === MSG_TYPE_DRAFT_REVIEWER) {
let avatar_url = detail.request_user_avatat_url;
let fromUser = detail.request_user_name;
let draftId = detail.draft_id;
let draftUrl = siteRoot + 'drafts/' + draftId + '/';
let notice = gettext('{from_user} has sent you a request for {draft_link}.');
let draftLink = '<a href=' + draftUrl + '>' + gettext('Draft') + '#' + draftId + '</a>';
notice = notice.replace('{from_user}', fromUser);
notice = notice.replace('{draft_link}', draftLink);
return {avatar_url, notice};
}
if (noticeType === MSG_TYPE_REPO_MONITOR) {
const {
op_user_avatar_url: avatar_url,

View File

@@ -1,146 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import toaster from '../toast';
import UserSelect from '../user-select';
import '../../css/add-reviewer-dialog.css';
const propTypes = {
showReviewerDialog: PropTypes.bool.isRequired,
draftID: PropTypes.string.isRequired,
toggleAddReviewerDialog: PropTypes.func.isRequired,
reviewers: PropTypes.array.isRequired
};
class AddReviewerDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
reviewers: this.props.reviewers,
selectedOption: null,
errorMsg: [],
loading: false,
};
this.Options = [];
}
listReviewers = () => {
seafileAPI.listDraftReviewers(this.props.draftID).then((res) => {
this.setState({ reviewers: res.data.reviewers });
});
};
handleSelectChange = (option) => {
this.setState({ selectedOption: option });
this.Options = [];
};
addReviewers = () => {
if (this.state.selectedOption.length > 0 ) {
this.refs.reviewSelect.clearSelect();
let reviewers = [];
for (let i = 0; i < this.state.selectedOption.length; i ++) {
reviewers[i] = this.state.selectedOption[i].email;
}
this.setState({
loading: true,
errorMsg: [],
});
seafileAPI.addDraftReviewers(this.props.draftID, reviewers).then((res) => {
if (res.data.failed.length > 0) {
let errorMsg = [];
for (let i = 0 ; i < res.data.failed.length ; i++) {
errorMsg[i] = res.data.failed[i];
}
this.setState({ errorMsg: errorMsg });
}
this.setState({
selectedOption: null,
loading: false
});
if (res.data.success.length > 0) {
this.listReviewers();
}
}).catch(error => {
let errorMsg = Utils.getErrorMsg(error);
toaster.danger(errorMsg);
});
}
};
deleteReviewer = (event) => {
let reviewer = event.target.getAttribute('name');
seafileAPI.deleteDraftReviewer(this.props.draftID, reviewer).then((res) => {
if (res.data === 200) {
let newReviewers = [];
for (let i = 0; i < this.state.reviewers.length; i ++) {
if (this.state.reviewers[i].user_email !== reviewer) {
newReviewers.push(this.state.reviewers[i]);
}
}
this.setState({ reviewers: newReviewers });
}
}).catch(error => {
let errorMsg = Utils.getErrorMsg(error);
toaster.danger(errorMsg);
});
};
render() {
const toggleDialog = this.props.toggleAddReviewerDialog;
const { reviewers, errorMsg } = this.state;
return (
<Modal isOpen={true} toggle={toggleDialog}>
<ModalHeader toggle={toggleDialog}>{gettext('Request a review')}</ModalHeader>
<ModalBody>
<p>{gettext('Add new reviewer')}</p>
<div className='add-reviewer'>
<UserSelect
placeholder={gettext('Search users')}
onSelectChange={this.handleSelectChange}
ref="reviewSelect"
isMulti={true}
className='reviewer-select'
/>
{(this.state.selectedOption && !this.state.loading)?
<Button color="secondary" onClick={this.addReviewers}>{gettext('Submit')}</Button> :
<Button color="secondary" disabled>{gettext('Submit')}</Button>
}
</div>
{errorMsg.length > 0 &&
errorMsg.map((item, index = 0, arr) => {
return (
<p className="reviewer-select-error error" key={index}>{errorMsg[index].email}
{': '}{errorMsg[index].error_msg}</p>
);
})
}
{reviewers.length > 0 &&
reviewers.map((item, index = 0, arr) => {
return (
<div className="reviewer-select-info" key={index}>
<div className="d-flex">
<img className="avatar reviewer-select-avatar" src={item.avatar_url} alt=""/>
<span className="reviewer-select-name ellipsis">{item.user_name}</span>
</div>
<i className="fa fa-times" name={item.user_email} onClick={this.deleteReviewer}></i>
</div>
);
})
}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={toggleDialog}>{gettext('Close')}</Button>
</ModalFooter>
</Modal>
);
}
}
AddReviewerDialog.propTypes = propTypes;
export default AddReviewerDialog;

View File

@@ -18,8 +18,6 @@ class CreateFile extends React.Component {
this.state = {
parentPath: '',
childName: props.fileType || '',
isMarkdownDraft: false,
isSdocDraft: false,
errMessage: '',
isSubmitBtnActive: props.fileType.slice(0, -5) ? true : false,
};
@@ -61,8 +59,7 @@ class CreateFile extends React.Component {
this.setState({errMessage: errMessage});
} else {
let path = this.state.parentPath + newName;
const { isMarkdownDraft, isSdocDraft } = this.state;
this.props.onAddFile(path, isMarkdownDraft, isSdocDraft);
this.props.onAddFile(path);
this.props.toggleDialog();
}
};
@@ -74,55 +71,6 @@ class CreateFile extends React.Component {
}
};
handleCheck = () => {
let pos = this.state.childName.lastIndexOf('.');
if (this.state.isMarkdownDraft) {
// from draft to not draft
// case 1, normally, the file name is ended with `(draft)`, like `test(draft).md`
// case 2, the file name is not ended with `(draft)`, the user has deleted some characters, like `test(dra.md`
let p = this.state.childName.substring(pos-7, pos);
let fileName = this.state.childName.substring(0, pos-7);
let fileType = this.state.childName.substring(pos);
if (p === '(draft)') {
// remove `(draft)` from file name
this.setState({
childName: fileName + fileType,
isMarkdownDraft: !this.state.isMarkdownDraft
});
} else {
// don't change file name
this.setState({
isMarkdownDraft: !this.state.isMarkdownDraft
});
}
}
if (!this.state.isMarkdownDraft) {
// from not draft to draft
// case 1, test.md ===> test(draft).md
// case 2, .md ===> (draft).md
// case 3, no '.' in the file name, don't change the file name
if (pos > 0) {
let fileName = this.state.childName.substring(0, pos);
let fileType = this.state.childName.substring(pos);
this.setState({
childName: fileName + '(draft)' + fileType,
isMarkdownDraft: !this.state.isMarkdownDraft
});
} else if (pos === 0 ) {
this.setState({
childName: '(draft)' + this.state.childName,
isMarkdownDraft: !this.state.isMarkdownDraft
});
} else {
this.setState({
isMarkdownDraft: !this.state.isMarkdownDraft
});
}
}
};
checkDuplicatedName = () => {
let isDuplicated = this.props.checkDuplicatedName(this.state.childName);
return isDuplicated;
@@ -134,12 +82,6 @@ class CreateFile extends React.Component {
this.newInput.current.setSelectionRange(0,0);
};
toggleMarkSdocDraft = (e) => {
this.setState({
isSdocDraft: e.target.checked
});
};
render() {
const { toggleDialog } = this.props;
return (
@@ -157,21 +99,6 @@ class CreateFile extends React.Component {
onChange={this.handleChange}
/>
</FormGroup>
{/*this.props.fileType == '.md' && isDocs && (
<FormGroup check>
<Label check>
<Input type="checkbox" onChange={this.handleCheck}/>{' '}{gettext('This is a draft')}
</Label>
</FormGroup>
)*/}
{/*this.props.fileType == '.sdoc' && (
<FormGroup check>
<Label check>
<Input type="checkbox" checked={isSdocDraft} onChange={this.toggleMarkSdocDraft}/>
<span>{gettext('Mark as draft')}</span>
</Label>
</FormGroup>
)*/}
</Form>
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Table } from 'reactstrap';
import { gettext, siteRoot, serviceURL } from '../../utils/constants';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
const propTypes = {
@@ -33,11 +33,8 @@ class ListCreatedFileDialog extends React.Component {
{
activity.createdFilesList.map((item, index) => {
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
if (item.name.endsWith('(draft).md')) {
fileURL = serviceURL + '/drafts/' + item.draft_id + '/';
}
let fileLink = <a href={fileURL} target='_blank' rel="noreferrer">{item.name}</a>;
if (item.name.endsWith('(draft).md') && !item.draft_id) {
if (item.name.endsWith('(draft).md')) { // be compatible with the existing draft files
fileLink = item.name;
}
return (

View File

@@ -1,142 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { gettext, siteRoot } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import moment from 'moment';
import editorUtilities from '../../utils/editor-utilities';
import toaster from '../../components/toast';
import { Utils } from '../../utils/utils';
import Draft from '../../models/draft';
const propTypes = {
repoID: PropTypes.string.isRequired,
toggle: PropTypes.func.isRequired,
};
class ListRepoDraftsDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
drafts: [],
};
}
componentDidMount() {
seafileAPI.listRepoDrafts(this.props.repoID).then(res => {
let drafts = res.data.drafts.map(item => {
let draft = new Draft(item);
return draft;
});
this.setState({
drafts: drafts
});
});
}
onDeleteDraftItem = (draft) => {
editorUtilities.deleteDraft(draft.id).then(() => {
let drafts = this.state.drafts.filter(item => {
return item.id !== draft.id;
});
this.setState({drafts: drafts});
let msg = gettext('Successfully deleted draft %(draft)s.');
msg = msg.replace('%(draft)s', draft.draftFilePath);
toaster.success(msg);
}).catch(() => {
let msg = gettext('Failed to delete draft %(draft)s.');
msg = msg.replace('%(draft)s', draft.draftFilePath);
toaster.danger(msg);
});
};
toggle = () => {
this.props.toggle();
};
render() {
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Drafts')}</ModalHeader>
<ModalBody className="dialog-list-container">
<table>
<thead>
<tr>
<th width='50%' className="ellipsis">{gettext('Name')}</th>
<th width='20%'>{gettext('Owner')}</th>
<th width='20%'>{gettext('Last Update')}</th>
<th width='10%'></th>
</tr>
</thead>
<tbody>
{this.state.drafts.map((item, index) => {
return (
<DraftItem
key={index}
draftItem={item}
onDeleteDraftItem={this.onDeleteDraftItem}
/>
);
})}
</tbody>
</table>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Close')}</Button>
</ModalFooter>
</Modal>
);
}
}
ListRepoDraftsDialog.propTypes = propTypes;
export default ListRepoDraftsDialog;
const DraftItemPropTypes = {
draftItem: PropTypes.object,
onDeleteDraftItem: PropTypes.func.isRequired,
};
class DraftItem extends React.Component {
constructor(props) {
super(props);
this.state = ({
active: false,
});
}
onMouseEnter = () => {
this.setState({
active: true
});
};
onMouseLeave = () => {
this.setState({
active: false
});
};
render() {
const draftItem = this.props.draftItem;
let href = siteRoot + 'drafts/' + draftItem.id + '/';
let className = this.state.active ? 'action-icon sf2-icon-x3' : 'action-icon vh sf2-icon-x3';
return (
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<td className="name">
<a href={href} target='_blank' rel="noreferrer">{Utils.getFileName(draftItem.draftFilePath)}</a>
</td>
<td>{draftItem.ownerNickname}</td>
<td>{moment(draftItem.createdStr).fromNow()}</td>
<td>
<i className={className} onClick={this.props.onDeleteDraftItem.bind(this, draftItem)}></i>
</td>
</tr>
);
}
}
DraftItem.propTypes = DraftItemPropTypes;

View File

@@ -1,32 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
const propTypes = {
deleteDraft: PropTypes.func.isRequired,
useDraft: PropTypes.func.isRequired,
localDraftDialog: PropTypes.bool.isRequired,
closeDraftDialog: PropTypes.func.isRequired,
};
class LocalDraftDialog extends React.PureComponent {
render() {
return (
<Modal isOpen={true} toggle={this.props.closeDraftDialog}>
<ModalHeader toggle={this.props.closeDraftDialog}>{gettext('Local draft')}</ModalHeader>
<ModalBody>
<p>{gettext('You have an unsaved draft. Do you like to use it?')}</p>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.props.useDraft}>{gettext('Use draft')}</Button>
<Button color="secondary" onClick={this.props.deleteDraft}>{gettext('Delete draft')}</Button>
</ModalFooter>
</Modal>
);
}
}
LocalDraftDialog.propTypes = propTypes;
export default LocalDraftDialog;

View File

@@ -2,17 +2,12 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Utils } from '../../utils/utils';
import { gettext, siteRoot } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import toaster from '../toast';
import SeafileMarkdownViewer from '../seafile-markdown-viewer';
const propTypes = {
path: PropTypes.string.isRequired,
repoID: PropTypes.string.isRequired,
hash: PropTypes.string,
isDraft: PropTypes.bool,
hasDraft: PropTypes.bool,
goDraftPage: PropTypes.func.isRequired,
isFileLoading: PropTypes.bool.isRequired,
isFileLoadedErr: PropTypes.bool.isRequired,
filePermission: PropTypes.string,
@@ -40,17 +35,6 @@ class DirColumnFile extends React.Component {
window.open(url);
};
onNewDraft = (e) => {
e.preventDefault();
let { path, repoID } = this.props;
seafileAPI.createDraft(repoID, path).then(res => {
window.location.href = siteRoot + 'lib/' + res.data.origin_repo_id + '/file' + res.data.draft_file_path + '?mode=edit';
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onOpenFile = (e) => {
e.preventDefault();
let { path, repoID } = this.props;
@@ -58,11 +42,6 @@ class DirColumnFile extends React.Component {
window.open(newUrl, '_blank');
};
goDraftPage = (e) => {
e.preventDefault();
this.props.goDraftPage();
};
render() {
if (this.props.isFileLoadedErr) {
return (
@@ -84,14 +63,6 @@ class DirColumnFile extends React.Component {
<span className='wiki-open-file position-fixed' onClick={this.onOpenFile}>
<i className="fas fa-expand-arrows-alt"></i>
</span>
{(!this.props.isDraft && this.props.hasDraft) &&
<div className='seafile-btn-view-review text-center mt-2'>
<div className='tag tag-green'>
{gettext('This file is in draft stage.')}
<span className="ml-2" onClick={this.goDraftPage}>{gettext('View Draft')}</span>
</div>
</div>
}
</Fragment>
</SeafileMarkdownViewer>
);

View File

@@ -28,9 +28,6 @@ const propTypes = {
isFileLoading: PropTypes.bool.isRequired,
isFileLoadedErr: PropTypes.bool.isRequired,
hash: PropTypes.string,
isDraft: PropTypes.bool.isRequired,
hasDraft: PropTypes.bool.isRequired,
goDraftPage: PropTypes.func.isRequired,
filePermission: PropTypes.string,
content: PropTypes.string,
lastModified: PropTypes.string,
@@ -38,7 +35,6 @@ const propTypes = {
onLinkClick: PropTypes.func.isRequired,
// repo content
isRepoInfoBarShow: PropTypes.bool.isRequired,
draftCounts: PropTypes.number.isRequired,
usedRepoTags: PropTypes.array.isRequired,
updateUsedRepoTags: PropTypes.func.isRequired,
// list
@@ -181,9 +177,6 @@ class DirColumnView extends React.Component {
path={this.props.path}
repoID={this.props.repoID}
hash={this.props.hash}
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
goDraftPage={this.props.goDraftPage}
isFileLoading={this.props.isFileLoading}
isFileLoadedErr={this.props.isFileLoadedErr}
filePermission={this.props.filePermission}
@@ -202,7 +195,6 @@ class DirColumnView extends React.Component {
enableDirPrivateShare={this.props.enableDirPrivateShare}
isRepoInfoBarShow={this.props.isRepoInfoBarShow}
usedRepoTags={this.props.usedRepoTags}
draftCounts={this.props.draftCounts}
updateUsedRepoTags={this.props.updateUsedRepoTags}
isDirentListLoading={this.props.isDirentListLoading}
direntList={this.props.direntList}

View File

@@ -8,7 +8,6 @@ const propTypes = {
path: PropTypes.string.isRequired,
repoID: PropTypes.string.isRequired,
currentRepoInfo: PropTypes.object.isRequired,
draftCounts: PropTypes.number,
usedRepoTags: PropTypes.array.isRequired,
updateUsedRepoTags: PropTypes.func.isRequired,
direntList: PropTypes.array.isRequired,
@@ -53,7 +52,6 @@ class DirGridView extends React.Component {
<RepoInfoBar
repoID={this.props.repoID}
currentPath={this.props.path}
draftCounts={this.props.draftCounts}
usedRepoTags={this.props.usedRepoTags}
updateUsedRepoTags={this.props.updateUsedRepoTags}
onFileTagChanged={this.props.onFileTagChanged}

View File

@@ -14,7 +14,6 @@ const propTypes = {
isRepoInfoBarShow: PropTypes.bool.isRequired,
repoTags: PropTypes.array.isRequired,
usedRepoTags: PropTypes.array.isRequired,
draftCounts: PropTypes.number,
updateUsedRepoTags: PropTypes.func.isRequired,
isDirentListLoading: PropTypes.bool.isRequired,
direntList: PropTypes.array.isRequired,
@@ -64,7 +63,6 @@ class DirListView extends React.Component {
<RepoInfoBar
repoID={this.props.repoID}
currentPath={this.props.path}
draftCounts={this.props.draftCounts}
usedRepoTags={this.props.usedRepoTags}
updateUsedRepoTags={this.props.updateUsedRepoTags}
onFileTagChanged={this.props.onFileTagChanged}

View File

@@ -181,12 +181,6 @@ class DirentGridView extends React.Component {
case 'Lock':
this.onLockItem(currentObject);
break;
case 'Mark as draft':
this.onMarkAsDraft(currentObject);
break;
case 'Unmark as draft':
this.onUnmarkAsDraft(currentObject);
break;
case 'History':
this.onHistory(currentObject);
break;
@@ -329,28 +323,6 @@ class DirentGridView extends React.Component {
});
};
onMarkAsDraft = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);
seafileAPI.sdocMarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(currentObject, 'is_sdoc_draft', true);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onUnmarkAsDraft = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);
seafileAPI.sdocUnmarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(currentObject, 'is_sdoc_draft', false);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onHistory = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);

View File

@@ -295,12 +295,6 @@ class DirentListItem extends React.Component {
case 'Convert to sdoc':
this.onItemConvert(event, 'sdoc');
break;
case 'Mark as draft':
this.onMarkAsDraft();
break;
case 'Unmark as draft':
this.onUnmarkAsDraft();
break;
case 'History':
this.onHistory();
break;
@@ -415,28 +409,6 @@ class DirentListItem extends React.Component {
});
};
onMarkAsDraft = () => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(this.props.dirent);
seafileAPI.sdocMarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(this.props.dirent, 'is_sdoc_draft', true);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onUnmarkAsDraft = () => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(this.props.dirent);
seafileAPI.sdocUnmarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(this.props.dirent, 'is_sdoc_draft', false);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onHistory = () => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(this.props.dirent);
@@ -779,9 +751,6 @@ class DirentListItem extends React.Component {
<a className="sf-link" onClick={this.onItemClick}>{dirent.name}</a> :
<a href={dirent.type === 'dir' ? dirHref : fileHref} onClick={this.onItemClick}>{dirent.name}</a>
}
{/*(Utils.isSdocFile(dirent.name) && dirent.is_sdoc_draft) &&
<span className="dirent-sdoc-draft-identifier">{gettext('Draft')}</span>
*/}
</Fragment>
)}
</td>

View File

@@ -1,126 +0,0 @@
import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import { gettext, siteRoot, lang } from '../../utils/constants';
import { Utils } from '../../utils/utils';
moment.locale(lang);
const propTypes = {
draft: PropTypes.object.isRequired,
isItemFreezed: PropTypes.bool.isRequired,
onFreezedItem: PropTypes.func.isRequired,
onUnfreezedItem: PropTypes.func.isRequired,
onDeleteHandler: PropTypes.func.isRequired,
onPublishHandler: PropTypes.func.isRequired,
};
class DraftListItem extends React.Component {
constructor(props) {
super(props);
this.state = {
isMenuIconShow: false,
isItemMenuShow: false,
highlight: false,
};
}
onMouseEnter = () => {
if (!this.props.isItemFreezed) {
this.setState({
isMenuIconShow: true,
highlight: true,
});
}
};
onMouseLeave = () => {
if (!this.props.isItemFreezed) {
this.setState({
isMenuIconShow: false,
highlight: false,
});
}
};
onDropdownToggleClick = (e) => {
e.preventDefault();
this.toggleOperationMenu(e);
};
toggleOperationMenu = (e) => {
e.stopPropagation();
this.setState(
{isItemMenuShow: !this.state.isItemMenuShow }, () => {
if (this.state.isItemMenuShow) {
this.props.onFreezedItem();
} else {
this.setState({
highlight: false,
isMenuIconShow: false,
});
this.props.onUnfreezedItem();
}
}
);
};
onDeleteHandler = () => {
this.props.onDeleteHandler(this.props.draft);
};
onPublishHandler = () => {
this.props.onPublishHandler(this.props.draft);
};
render() {
let draft = this.props.draft;
let repoID = draft.origin_repo_id;
let filePath = draft.draft_file_path;
let fileName = Utils.getFileName(filePath);
let draftUrl = siteRoot + 'drafts/' + draft.id + '/';
let libraryUrl = siteRoot + 'library/' + repoID + '/' + encodeURIComponent(draft.repo_name) + '/' ;
let localTime = moment.utc(draft.updated_at).toDate();
localTime = moment(localTime).fromNow();
let iconUrl = Utils.getFileIconUrl(fileName);
return (
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<td className="text-center"><img src={iconUrl} width="24" alt='' /></td>
<td className="name" >
<a href={draftUrl} target="_blank" rel="noreferrer">{fileName}</a>
</td>
<td className="library">
<a href={libraryUrl} target="_blank" rel="noreferrer">{draft.repo_name}</a>
</td>
<td className="update">{localTime}</td>
<td className="text-center">
{this.state.isMenuIconShow && (
<Dropdown isOpen={this.state.isItemMenuShow} toggle={this.toggleOperationMenu}>
<DropdownToggle
tag="i"
className="fas fa-ellipsis-v attr-action-icon"
title={gettext('More operations')}
aria-label={gettext('More operations')}
onClick={this.onDropdownToggleClick}
data-toggle="dropdown"
aria-expanded={this.state.isItemMenuShow}
/>
<DropdownMenu>
<DropdownItem onClick={this.onDeleteHandler}>{gettext('Delete')}</DropdownItem>
{draft.status == 'open' &&
<DropdownItem onClick={this.onPublishHandler}>{gettext('Publish')}</DropdownItem>
}
</DropdownMenu>
</Dropdown>
)}
</td>
</tr>
);
}
}
DraftListItem.propTypes = propTypes;
export default DraftListItem;

View File

@@ -1,64 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import DraftListItem from './draft-list-item';
const propTypes = {
draftList: PropTypes.array.isRequired,
onDeleteHandler: PropTypes.func.isRequired,
onPublishHandler: PropTypes.func.isRequired,
};
class DraftListView extends React.Component {
constructor(props) {
super(props);
this.state = {
isItemFreezed: false,
};
}
onFreezedItem = () => {
this.setState({isItemFreezed: true});
};
onUnfreezedItem = () => {
this.setState({isItemFreezed: false});
};
render() {
let drafts = this.props.draftList;
return (
<table>
<thead>
<tr>
<th style={{width: '4%'}}>{/*img*/}</th>
<th style={{width: '46%'}}>{gettext('Name')}</th>
<th style={{width: '30%'}}>{gettext('Library')}</th>
<th style={{width: '10%'}}>{gettext('Last Update')}</th>
<th style={{width: '10%'}}></th>
</tr>
</thead>
<tbody>
{ drafts && drafts.map((draft) => {
return (
<DraftListItem
key={draft.id}
draft={draft}
isItemFreezed={this.state.isItemFreezed}
onFreezedItem={this.onFreezedItem}
onUnfreezedItem={this.onUnfreezedItem}
onDeleteHandler={this.props.onDeleteHandler}
onPublishHandler={this.props.onPublishHandler}
/>
);
})}
</tbody>
</table>
);
}
}
DraftListView.propTypes = propTypes;
export default DraftListView;

View File

@@ -12,7 +12,6 @@ import { canViewOrg, isDocs, isPro, isDBSqlite3, customNavItems } from '../utils
const propTypes = {
currentTab: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
tabItemClick: PropTypes.func.isRequired,
draftCounts: PropTypes.number,
};
class MainSideNav extends React.Component {
@@ -251,15 +250,6 @@ class MainSideNav extends React.Component {
<span className="nav-text">{gettext('Published Libraries')}</span>
</Link>
</li>
{/*isDocs &&
<li className="nav-item" onClick={(e) => this.tabItemClick(e, 'drafts')}>
<Link className={`nav-link ellipsis ${this.getActiveClass('drafts')}`} to={siteRoot + 'drafts/'} title={gettext('Drafts')}>
<span className="sf2-icon-edit" aria-hidden="true"></span>
<span className="nav-text">{gettext('Drafts')}</span>
{this.props.draftCounts > 0 && <span id="draft-num">{this.props.draftCounts}</span>}
</Link>
</li>
*/}
<li className="nav-item">
<Link className={`nav-link ellipsis ${this.getActiveClass('linked-devices')}`} to={siteRoot + 'linked-devices/'} title={gettext('Linked Devices')} onClick={(e) => this.tabItemClick(e, 'linked-devices')}>
<span className="sf2-icon-monitor" aria-hidden="true"></span>

View File

@@ -2,14 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types';
import ModalPortal from './modal-portal';
import ListTaggedFilesDialog from './dialog/list-taggedfiles-dialog';
import ListRepoDraftsDialog from './dialog/list-repo-drafts-dialog';
import '../css/repo-info-bar.css';
const propTypes = {
repoID: PropTypes.string.isRequired,
usedRepoTags: PropTypes.array.isRequired,
draftCounts: PropTypes.number,
updateUsedRepoTags: PropTypes.func,
onFileTagChanged: PropTypes.func,
className: PropTypes.string,
@@ -24,7 +22,6 @@ class RepoInfoBar extends React.Component {
this.state = {
currentTag: null,
isListTaggedFileShow: false,
showRepoDrafts: false
};
}
@@ -41,19 +38,8 @@ class RepoInfoBar extends React.Component {
});
};
toggleDrafts = () => {
this.setState({
showRepoDrafts: !this.state.showRepoDrafts
});
};
render() {
let { repoID, usedRepoTags, draftCounts, className } = this.props;
// to be compatible with the existing code
if (draftCounts === undefined) {
draftCounts = 0;
}
let { repoID, usedRepoTags, className } = this.props;
return (
<div className={`repo-info-bar ${className ? className : ''}`}>
@@ -72,17 +58,6 @@ class RepoInfoBar extends React.Component {
})}
</ul>
)}
{/*<div className={usedRepoTags.length > 0 ? 'file-info-list mt-1' : 'file-info-list'}>
{draftCounts > 0 &&
<span className="file-info">
<span className="info-icon sf2-icon-drafts"></span>
<span className="used-tag-name">{gettext('draft')}</span>
<button type="button" className="used-tag-files border-0 bg-transparent" onClick={this.toggleDrafts}>
{draftCounts > 1 ? draftCounts + ' files' : draftCounts + ' file'}
</button>
</span>
}
</div>*/}
{this.state.isListTaggedFileShow && (
<ModalPortal>
<ListTaggedFilesDialog
@@ -97,16 +72,6 @@ class RepoInfoBar extends React.Component {
/>
</ModalPortal>
)}
{this.state.showRepoDrafts && (
<ModalPortal>
<ListRepoDraftsDialog
toggle={this.toggleDrafts}
repoID={this.props.repoID}
/>
</ModalPortal>
)}
</div>
);
}

View File

@@ -9,7 +9,6 @@ const propTypes = {
currentTab: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
onCloseSidePanel: PropTypes.func.isRequired,
tabItemClick: PropTypes.func.isRequired,
draftCounts: PropTypes.number,
};
class SidePanel extends React.Component {
@@ -21,7 +20,7 @@ class SidePanel extends React.Component {
<Logo onCloseSidePanel={this.props.onCloseSidePanel}/>
</div>
<div className="side-panel-center">
<MainSideNav tabItemClick={this.props.tabItemClick} currentTab={this.props.currentTab} draftCounts={this.props.draftCounts}/>
<MainSideNav tabItemClick={this.props.tabItemClick} currentTab={this.props.currentTab} />
</div>
<div className="side-panel-footer">
<SideNavFooter />

View File

@@ -126,28 +126,6 @@ class MultipleDirOperationToolbar extends React.Component {
});
};
onMarkAsDraft = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
seafileAPI.sdocMarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(dirent, 'is_sdoc_draft', true);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onUnmarkAsDraft = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
seafileAPI.sdocUnmarkAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(dirent, 'is_sdoc_draft', false);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onStartRevise = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
@@ -206,12 +184,6 @@ class MultipleDirOperationToolbar extends React.Component {
case 'Unlock':
this.unlockFile(dirent);
break;
case 'Mark as draft':
this.onMarkAsDraft(dirent);
break;
case 'Unmark as draft':
this.onUnmarkAsDraft(dirent);
break;
case 'History':
this.onHistory(dirent);
break;

View File

@@ -1,10 +1,8 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { DropdownToggle, Dropdown, DropdownMenu, DropdownItem, Tooltip} from 'reactstrap';
import { gettext, siteRoot, isDocs } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { DropdownToggle, Dropdown, DropdownMenu, DropdownItem } from 'reactstrap';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import toaster from '../toast';
import ModalPotal from '../modal-portal';
import ShareDialog from '../dialog/share-dialog';
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
@@ -18,8 +16,6 @@ const propTypes = {
enableDirPrivateShare: PropTypes.bool.isRequired,
isGroupOwnedRepo: PropTypes.bool.isRequired,
filePermission: PropTypes.string,
isDraft: PropTypes.bool.isRequired,
hasDraft: PropTypes.bool.isRequired,
fileTags: PropTypes.array.isRequired,
onFileTagChanged: PropTypes.func.isRequired,
showShareBtn: PropTypes.bool.isRequired,
@@ -31,7 +27,6 @@ class ViewFileToolbar extends React.Component {
constructor(props) {
super(props);
this.state = {
isDraftMessageShow: false,
isMoreMenuShow: false,
isShareDialogShow: false,
isEditTagDialogShow: false,
@@ -45,21 +40,6 @@ class ViewFileToolbar extends React.Component {
window.open(url);
};
onNewDraft = (e) => {
e.preventDefault();
let { path, repoID } = this.props;
seafileAPI.createDraft(repoID, path).then(res => {
window.location.href = siteRoot + 'lib/' + res.data.origin_repo_id + '/file' + res.data.draft_file_path + '?mode=edit';
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
onDraftHover = () => {
this.setState({isDraftMessageShow: !this.state.isDraftMessageShow});
};
toggleMore = () => {
this.setState({isMoreMenuShow: !this.state.isMoreMenuShow});
};
@@ -82,17 +62,11 @@ class ViewFileToolbar extends React.Component {
return (
<Fragment>
<div className="dir-operation">
{((filePermission === 'rw' || filePermission === 'cloud-edit') && !this.props.hasDraft) && (
{(filePermission === 'rw' || filePermission === 'cloud-edit') && (
<Fragment>
<button className="btn btn-secondary operation-item" title={gettext('Edit File')} onClick={this.onEditClick}>{gettext('Edit')}</button>
</Fragment>
)}
{(filePermission === 'rw' && !this.props.isDraft && !this.props.hasDraft && isDocs) && (
<Fragment>
<button id="new-draft" className="btn btn-secondary operation-item" onClick={this.onNewDraft}>{gettext('New Draft')}</button>
<Tooltip target="new-draft" placement="bottom" isOpen={this.state.isDraftMessageShow} toggle={this.onDraftHover}>{gettext('Create a draft from this file, instead of editing it directly.')}</Tooltip>
</Fragment>
)}
{filePermission === 'rw' && (
<Dropdown isOpen={this.state.isMoreMenuShow} toggle={this.toggleMore}>
<DropdownToggle className='btn btn-secondary operation-item'>

View File

@@ -1,38 +0,0 @@
.reviewer-select-info {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.reviewer-select-avatar {
margin-right: 10px;
}
.reviewer-select-name {
height: 2rem;
line-height: 2rem;
}
.reviewer-select-error {
margin-top: 1em;
}
.reviewer-select .true__dropdown-indicator, .reviewer-select .true__indicator-separator {
display: none;
}
.reviewer-select-info i {
opacity: 0;
margin-right: 10px;
}
.reviewer-select-info:hover i {
cursor: pointer;
opacity: 1;
color: #a4a4a4;
}
.add-reviewer {
display: flex;
justify-content: space-between;
}
.add-reviewer .reviewer-select {
width: 385px;
}
.add-reviewer .btn {
width: 75px;
}

View File

@@ -25,8 +25,6 @@ class Acticity {
this.old_name = json.old_name;
} else if (json.op_type === 'publish') {
this.old_path = json.old_path;
} else if (json.name.endsWith('(draft).md')) {
this.draft_id = json.draft_id;
}
}
}

View File

@@ -42,7 +42,6 @@ class Dirent {
this.encoded_thumbnail_src = json.encoded_thumbnail_src;
}
if (Utils.isSdocFile(json.name)) {
this.is_sdoc_draft = json.is_sdoc_draft || false;
this.is_sdoc_revision = json.is_sdoc_revision || false;
this.revision_id = json.revision_id || null;
}

View File

@@ -1,15 +0,0 @@
import moment from 'moment';
class Draft {
constructor(item) {
this.created = item.created_at;
this.createdStr = moment((new Date(item.created_at)).getTime()).format('YYYY-MM-DD HH:mm');
this.id = item.id;
this.ownerNickname = item.owner_nickname;
this.originRepoID = item.origin_repo_id;
this.draftFilePath = item.draft_file_path;
}
}
export default Draft;

View File

@@ -1,14 +0,0 @@
import moment from 'moment';
class Review {
constructor(item) {
this.created = item.created_at;
this.createdStr = moment((new Date(item.created_at)).getTime()).format('YYYY-MM-DD HH:mm');
this.id = item.id;
this.creatorName = item.creator_name;
this.draftFilePath = item.draft_file_path;
}
}
export default Review;

View File

@@ -1,7 +1,7 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { gettext, siteRoot, serviceURL } from '../../utils/constants';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import ListCreatedFileDialog from '../../components/dialog/list-created-files-dialog';
import ModalPortal from '../../components/modal-portal';
@@ -70,21 +70,9 @@ class ActivityItem extends Component {
moreDetails = true;
break;
}
} else if (item.obj_type == 'draft') {
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
let fileLink = <a href={fileURL} target="_blank" rel="noreferrer">{item.name}</a>;
op = gettext('Publish draft');
details = fileLink;
moreDetails = true;
} else if (item.obj_type == 'files') {
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
if (item.name.endsWith('(draft).md')) {
fileURL = serviceURL + '/drafts/' + item.draft_id + '/';
}
let fileLink = `<a href=${fileURL} target="_blank">${item.name}</a>`;
if (item.name.endsWith('(draft).md') && !item.draft_id) {
fileLink = item.name;
}
let fileCount = item.createdFilesCount - 1;
let firstLine = gettext('{file} and {n} other files')
.replace('{file}', fileLink)
@@ -99,10 +87,10 @@ class ActivityItem extends Component {
moreDetails = true;
} else if (item.obj_type == 'file') {
const isDraft = item.name.endsWith('(draft).md');
const fileURL = isDraft ? serviceURL + '/drafts/' + item.draft_id + '/' :
const fileURL = isDraft ? '' :
`${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
let fileLink = <a href={fileURL} target="_blank" rel="noreferrer">{item.name}</a>;
if (isDraft && !item.draft_id) {
if (isDraft) {
fileLink = item.name;
}
switch (item.op_type) {

View File

@@ -1,82 +0,0 @@
import React, { Fragment } from 'react';
import { gettext } from '../../utils/constants';
import editUtilities from '../../utils/editor-utilities';
import { Utils } from '../../utils/utils';
import PropTypes from 'prop-types';
import toaster from '../../components/toast';
import EmptyTip from '../../components/empty-tip';
import Loading from '../../components/loading';
import DraftListView from '../../components/draft-list-view/draft-list-view';
const propTypes = {
isLoadingDraft: PropTypes.bool.isRequired,
updateDraftsList: PropTypes.func.isRequired,
draftList: PropTypes.array.isRequired,
getDrafts: PropTypes.func.isRequired,
};
class DraftContent extends React.Component {
componentDidMount() {
this.props.getDrafts();
}
onDeleteHandler = (draft) => {
// let draft = this.state.currentDraft;
let draft_name = Utils.getFileName(draft.draft_file_path);
editUtilities.deleteDraft(draft.id).then(res => {
this.props.updateDraftsList(draft.id);
let msg_s = gettext('Successfully deleted draft %(draft)s.');
msg_s = msg_s.replace('%(draft)s', draft_name);
toaster.success(msg_s);
}).catch(() => {
let msg_s = gettext('Failed to delete draft %(draft)s.');
msg_s = msg_s.replace('%(draft)s', draft_name);
toaster.danger(msg_s);
});
};
onPublishHandler = (draft) => {
// let draft = this.state.currentDraft;
let draft_name = Utils.getFileName(draft.draft_file_path);
editUtilities.publishDraft(draft.id).then(res => {
this.props.updateDraftsList(draft.id);
let msg_s = gettext('Successfully published draft %(draft)s.');
msg_s = msg_s.replace('%(draft)s', draft_name);
toaster.success(msg_s);
}).catch(() => {
let msg_s = gettext('Failed to publish draft %(draft)s.');
msg_s = msg_s.replace('%(draft)s', draft_name);
toaster.danger(msg_s);
});
};
render() {
return (
<div className="cur-view-content">
{this.props.isLoadingDraft && <Loading />}
{!this.props.isLoadingDraft && (
<Fragment>
{this.props.draftList.length === 0 && (
<EmptyTip>
<h2>{gettext('No draft yet')}</h2>
<p>{gettext('Draft is a way to let you collaborate with others on files. You can create a draft from a file, edit the draft and then ask for a review. The original file will be updated only after the draft has been reviewed.')}</p>
</EmptyTip>
)}
{this.props.draftList.length !==0 && (
<DraftListView
draftList={this.props.draftList}
onDeleteHandler={this.onDeleteHandler}
onPublishHandler={this.onPublishHandler}
/>
)}
</Fragment>
)}
</div>
);
}
}
DraftContent.propTypes = propTypes;
export default DraftContent;

View File

@@ -1,31 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
const propTypes = {
children: PropTypes.oneOfType([
PropTypes.array,
PropTypes.object
]).isRequired,
};
class DraftsView extends React.Component {
render() {
return (
<div className="main-panel-center">
<div className="cur-view-container">
<div className="cur-view-path">
<div className="path-container">
<h3 className="sf-heading">{gettext('Drafts')}</h3>
</div>
</div>
{this.props.children}
</div>
</div>
);
}
}
DraftsView.propTypes = propTypes;
export default DraftsView;

View File

@@ -28,10 +28,7 @@ const propTypes = {
isViewFile: PropTypes.bool.isRequired,
isFileLoadedErr: PropTypes.bool.isRequired,
hash: PropTypes.string,
isDraft: PropTypes.bool.isRequired,
hasDraft: PropTypes.bool.isRequired,
fileTags: PropTypes.array.isRequired,
goDraftPage: PropTypes.func.isRequired,
isFileLoading: PropTypes.bool.isRequired,
filePermission: PropTypes.string,
content: PropTypes.string,
@@ -50,7 +47,6 @@ const propTypes = {
onAddFileNode: PropTypes.func.isRequired,
onAddFolderNode: PropTypes.func.isRequired,
// repo content
draftCounts: PropTypes.number,
repoTags: PropTypes.array.isRequired,
usedRepoTags: PropTypes.array.isRequired,
updateUsedRepoTags: PropTypes.func.isRequired,
@@ -164,10 +160,10 @@ class LibContentContainer extends React.Component {
};
render() {
let { path, repoID, usedRepoTags, draftCounts } = this.props;
let { path, repoID, usedRepoTags } = this.props;
let isRepoInfoBarShow = false;
if (path === '/') {
if (usedRepoTags.length !== 0 || draftCounts !== 0) {
if (usedRepoTags.length !== 0) {
isRepoInfoBarShow = true;
}
}
@@ -214,7 +210,6 @@ class LibContentContainer extends React.Component {
isRepoInfoBarShow={isRepoInfoBarShow}
repoTags={this.props.repoTags}
usedRepoTags={this.props.usedRepoTags}
draftCounts={this.props.draftCounts}
updateUsedRepoTags={this.props.updateUsedRepoTags}
isDirentListLoading={this.props.isDirentListLoading}
direntList={this.props.direntList}
@@ -256,7 +251,6 @@ class LibContentContainer extends React.Component {
isRepoInfoBarShow={isRepoInfoBarShow}
repoTags={this.props.repoTags}
usedRepoTags={this.props.usedRepoTags}
draftCounts={this.props.draftCounts}
updateUsedRepoTags={this.props.updateUsedRepoTags}
isDirentListLoading={this.props.isDirentListLoading}
direntList={this.props.direntList}
@@ -298,9 +292,6 @@ class LibContentContainer extends React.Component {
isFileLoading={this.props.isFileLoading}
isFileLoadedErr={this.props.isFileLoadedErr}
hash={this.props.hash}
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
goDraftPage={this.props.goDraftPage}
filePermission={this.props.filePermission}
content={this.props.content}
lastModified={this.props.lastModified}
@@ -309,7 +300,6 @@ class LibContentContainer extends React.Component {
isRepoInfoBarShow={isRepoInfoBarShow}
repoTags={this.props.repoTags}
usedRepoTags={this.props.usedRepoTags}
draftCounts={this.props.draftCounts}
updateUsedRepoTags={this.props.updateUsedRepoTags}
isDirentListLoading={this.props.isDirentListLoading}
direntList={this.props.direntList}

View File

@@ -11,8 +11,6 @@ import { Utils } from '../../utils/utils';
const propTypes = {
isViewFile: PropTypes.bool.isRequired,
filePermission: PropTypes.string,
isDraft: PropTypes.bool.isRequired,
hasDraft: PropTypes.bool.isRequired,
fileTags: PropTypes.array.isRequired,
onFileTagChanged: PropTypes.func.isRequired, // for file-view-toolbar
// side-panel
@@ -73,8 +71,6 @@ class LibContentToolbar extends React.Component {
enableDirPrivateShare={this.props.enableDirPrivateShare}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
filePermission={this.props.filePermission}
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
fileTags={this.props.fileTags}
onFileTagChanged={this.props.onFileTagChanged}
showShareBtn={this.props.showShareBtn}

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import cookie from 'react-cookies';
import moment from 'moment';
import { navigate } from '@gatsbyjs/reach-router';
import { gettext, siteRoot, username, isDocs, enableVideoThumbnail } from '../../utils/constants';
import { gettext, siteRoot, username, enableVideoThumbnail } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import collabServer from '../../utils/collab-server';
@@ -46,11 +46,7 @@ class LibContentView extends React.Component {
isGroupOwnedRepo: false,
userPerm: '',
selectedDirentList: [],
isDraft: false,
hasDraft: false,
fileTags: [],
draftID: '',
draftCounts: 0,
repoTags: [],
usedRepoTags: [],
isTreeDataLoading: true,
@@ -296,7 +292,7 @@ class LibContentView extends React.Component {
// update data
seafileAPI.getFileInfo(repoID, filePath).then((res) => {
let { mtime, permission, last_modifier_name, is_draft, has_draft, draft_id } = res.data;
let { mtime, permission, last_modifier_name } = res.data;
seafileAPI.getFileDownloadLink(repoID, filePath).then((res) => {
seafileAPI.getFileContent(res.data).then((res) => {
if (this.state.content !== res.data) {
@@ -309,9 +305,6 @@ class LibContentView extends React.Component {
lastModified: moment.unix(mtime).fromNow(),
isFileLoading: false,
isFileLoadedErr: false,
isDraft: is_draft,
hasDraft: has_draft,
draftID: draft_id
});
});
});
@@ -333,18 +326,6 @@ class LibContentView extends React.Component {
// list used FileTags
this.updateUsedRepoTags();
// list draft counts and review counts
if (isDocs) {
seafileAPI.getRepoDraftCounts(repoID).then(res => {
this.setState({
draftCounts: res.data.draft_counts,
});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
if (Utils.isMarkdownFile(path)) {
seafileAPI.getFileInfo(this.props.repoID, path).then(() => {
if (this.state.currentMode !== 'column') {
@@ -441,7 +422,7 @@ class LibContentView extends React.Component {
// update data
seafileAPI.getFileInfo(repoID, filePath).then((res) => {
let { mtime, permission, last_modifier_name, is_draft, has_draft, draft_id } = res.data;
let { mtime, permission, last_modifier_name } = res.data;
seafileAPI.getFileDownloadLink(repoID, filePath).then((res) => {
seafileAPI.getFileContent(res.data).then((res) => {
this.setState({
@@ -451,9 +432,6 @@ class LibContentView extends React.Component {
lastModified: moment.unix(mtime).fromNow(),
isFileLoading: false,
isFileLoadedErr: false,
isDraft: is_draft,
hasDraft: has_draft,
draftID: draft_id
});
});
});
@@ -897,26 +875,15 @@ class LibContentView extends React.Component {
});
};
onAddFile = (filePath, isMarkdownDraft, isSdocDraft) => {
onAddFile = (filePath) => {
let repoID = this.props.repoID;
seafileAPI.createFile(repoID, filePath, isMarkdownDraft).then(res => {
seafileAPI.createFile(repoID, filePath).then(res => {
let name = Utils.getFileName(filePath);
let parentPath = Utils.getDirName(filePath);
if (this.state.currentMode === 'column') {
this.addNodeToTree(name, parentPath, 'file');
}
if (parentPath === this.state.path && !this.state.isViewFile) {
if (isSdocDraft) { // the new file is marked to be draft
seafileAPI.sdocMarkAsDraft(repoID, filePath).then((res) => {
this.addDirent(name, 'file', res.data.size, isSdocDraft);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
this.addDirent(name, 'file', res.data.size);
});
return;
}
this.addDirent(name, 'file', res.data.size);
}
}).catch((error) => {
@@ -1470,8 +1437,8 @@ class LibContentView extends React.Component {
}
};
addDirent = (name, type, size, isSdocDraft) => {
let item = this.createDirent(name, type, size, isSdocDraft);
addDirent = (name, type, size) => {
let item = this.createDirent(name, type, size);
let direntList = this.state.direntList;
if (type === 'dir') {
direntList.unshift(item);
@@ -1810,14 +1777,11 @@ class LibContentView extends React.Component {
return new TreeNode({object});
}
createDirent(name, type, size, isSdocDraft) {
createDirent(name, type, size) {
// use current dirent parent's permission as it's permission
const { userPerm: permission } = this.state;
const mtime = new Date().getTime()/1000;
const obj = { name, type, mtime, size, permission };
if (isSdocDraft) {
obj.is_sdoc_draft = isSdocDraft;
}
const dirent = new Dirent(obj);
return dirent;
}
@@ -1903,10 +1867,6 @@ class LibContentView extends React.Component {
}
};
goDraftPage = () => {
window.open(siteRoot + 'drafts/' + this.state.draftID + '/');
};
sortItems = (sortBy, sortOrder) => {
cookie.save('seafile-repo-dir-sort-by', sortBy);
cookie.save('seafile-repo-dir-sort-order', sortOrder);
@@ -2043,8 +2003,6 @@ class LibContentView extends React.Component {
<LibContentToolbar
isViewFile={this.state.isViewFile}
filePermission={this.state.filePermission}
isDraft={this.state.isDraft}
hasDraft={this.state.hasDraft}
fileTags={this.state.fileTags}
onFileTagChanged={this.onToolbarFileTagChanged}
onSideNavMenuClick={this.props.onMenuClick}
@@ -2095,10 +2053,7 @@ class LibContentView extends React.Component {
onMainNavBarClick={this.onMainNavBarClick}
isViewFile={this.state.isViewFile}
hash={this.state.hash}
isDraft={this.state.isDraft}
hasDraft={this.state.hasDraft}
fileTags={this.state.fileTags}
goDraftPage={this.goDraftPage}
isFileLoading={this.state.isFileLoading}
isFileLoadedErr={this.state.isFileLoadedErr}
filePermission={this.state.filePermission}
@@ -2116,7 +2071,6 @@ class LibContentView extends React.Component {
onAddFileNode={this.onAddFile}
onRenameNode={this.onRenameTreeNode}
onDeleteNode={this.onDeleteTreeNode}
draftCounts={this.state.draftCounts}
repoTags={this.state.repoTags}
usedRepoTags={this.state.usedRepoTags}
updateUsedRepoTags={this.updateUsedRepoTags}

View File

@@ -1,7 +1,7 @@
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
const { repoID, repoName, filePath, fileName, draftID } = window.app.pageOptions;
const { repoID, repoName, filePath, fileName } = window.app.pageOptions;
const { serviceUrl } = window.app.config;
const userInfo = window.app.userInfo;
const userName = userInfo.username;
@@ -137,10 +137,6 @@ class EditorApi {
return seafileAPI.deleteShareLink(token);
}
getDraftKey() {
return (repoID + filePath);
}
getFileContent(url) {
return seafileAPI.getFileContent(url);
}
@@ -157,22 +153,6 @@ class EditorApi {
return seafileAPI.getUserAvatar(userName, size);
}
goDraftPage() {
window.location.href = serviceUrl + '/drafts/' + draftID + '/';
}
createDraftFile() {
return seafileAPI.createDraft(repoID, filePath).then(res => {
window.location.href = serviceUrl + '/lib/' + res.data.origin_repo_id + '/file' + Utils.encodePath(res.data.draft_file_path) + '?mode=edit';
});
}
publishDraftFile() {
return seafileAPI.publishDraft(draftID).then(res => {
window.location.href = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(res.data.published_file_path);
});
}
fileMetaData() {
return seafileAPI.fileMetaData(repoID, filePath);
}

View File

@@ -37,9 +37,6 @@ class FileInfo extends React.PureComponent {
<div className="file-state">
<span className={'file-modifier-name'}>{fileInfo.lastModifier}</span>
<span className={'file-modifier-time'}>{modifyTime}</span>
{this.props.showDraftSaved && (
<span className={'file-modifier-savedraft'}>{gettext('Local draft saved')}</span>
)}
</div>
</div>
);
@@ -52,7 +49,6 @@ FileInfo.propTypes = {
isLocked: PropTypes.bool,
mediaUrl: PropTypes.string,
toggleStar: PropTypes.func,
showDraftSaved: PropTypes.bool,
};
export default FileInfo;

View File

@@ -13,15 +13,11 @@ const { seafileCollabServer } = window.app.config;
const { canDownloadFile } = window.app.pageOptions;
const propTypes = {
isDocs: PropTypes.bool.isRequired,
hasDraft: PropTypes.bool.isRequired,
isDraft: PropTypes.bool.isRequired,
editorApi: PropTypes.object.isRequired,
collabUsers: PropTypes.array.isRequired,
fileInfo: PropTypes.object.isRequired,
toggleShareLinkDialog: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
toggleNewDraft: PropTypes.func.isRequired,
toggleStar: PropTypes.func.isRequired,
openDialogs: PropTypes.func.isRequired,
showFileHistory: PropTypes.bool.isRequired,
@@ -31,7 +27,6 @@ const propTypes = {
contentChanged: PropTypes.bool.isRequired,
saving: PropTypes.bool.isRequired,
onSaveEditorContent: PropTypes.func.isRequired,
showDraftSaved: PropTypes.bool.isRequired,
isLocked: PropTypes.bool.isRequired,
lockedByMe: PropTypes.bool.isRequired,
toggleLockFile: PropTypes.func.isRequired,
@@ -68,7 +63,6 @@ class HeaderToolbar extends React.Component {
toggleStar={this.props.toggleStar}
editorApi={this.props.editorApi}
fileInfo={this.props.fileInfo}
showDraftSaved={this.props.showDraftSaved}
isLocked={isLocked}
isPro={isPro}
mediaUrl={mediaUrl}
@@ -154,7 +148,6 @@ class HeaderToolbar extends React.Component {
toggleStar={this.props.toggleStar}
editorApi={this.props.editorApi}
fileInfo={this.props.fileInfo}
showDraftSaved={this.props.showDraftSaved}
/>
<div className="topbar-btn-container">
<ButtonGroup>

View File

@@ -3,7 +3,7 @@ import io from 'socket.io-client';
import { EXTERNAL_EVENTS, EventBus, RichMarkdownEditor } from '@seafile/seafile-editor';
import { Utils } from '../../utils/utils';
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, isDocs, mediaUrl } from '../../utils/constants';
import { gettext, mediaUrl } from '../../utils/constants';
import toaster from '../../components/toast';
import ShareDialog from '../../components/dialog/share-dialog';
import InsertFileDialog from '../../components/dialog/insert-file-dialog';
@@ -16,7 +16,7 @@ import './css/markdown-editor.css';
const CryptoJS = require('crypto-js');
const URL = require('url-parse');
const { repoID, filePath, fileName, isDraft, hasDraft, isLocked, lockedByMe } = window.app.pageOptions;
const { repoID, filePath, fileName, isLocked, lockedByMe } = window.app.pageOptions;
const { siteRoot, serviceUrl, seafileCollabServer } = window.app.config;
const userInfo = window.app.userInfo;
const IMAGE_SUFFIXES = ['png', 'PNG', 'jpg', 'JPG', 'jpeg', 'JPEG', 'gif', 'GIF'];
@@ -42,11 +42,9 @@ class MarkdownEditor extends React.Component {
},
editorMode: 'rich',
collabServer: seafileCollabServer ? seafileCollabServer : null,
localDraftDialog: false,
showMarkdownEditorDialog: false,
showShareLinkDialog: false,
showInsertFileDialog: false,
showDraftSaved: false,
collabUsers: userInfo ?
[{user: userInfo, is_editing: false}] : [],
value: null,
@@ -61,10 +59,6 @@ class MarkdownEditor extends React.Component {
};
this.timer = null;
this.localDraft = '';
this.autoSave = false;
this.draftRichValue = '';
this.draftPlainValue = '';
if (this.state.collabServer) {
const socket = io(this.state.collabServer);
@@ -179,50 +173,6 @@ class MarkdownEditor extends React.Component {
this.setState({editorMode: editorMode});
};
setDraftValue = (type, value) => {
if (type === 'rich') {
this.draftRichValue = value;
} else {
this.draftPlainValue = value;
}
};
checkDraft = () => {
let draftKey = editorApi.getDraftKey();
let draft = localStorage.getItem(draftKey);
let that = this;
if (draft) {
that.setState({localDraftDialog: true});
that.localDraft = draft;
localStorage.removeItem(draftKey);
}
};
useDraft = () => {
this.setState({
localDraftDialog: false,
loading: false,
markdownContent: this.localDraft,
editorMode: 'rich',
});
this.emitSwitchEditor(true);
};
deleteDraft = () => {
if (this.state.localDraftDialog) {
this.setState({
localDraftDialog: false,
loading: false,
});
}
let draftKey = editorApi.getDraftKey();
localStorage.removeItem(draftKey);
};
closeDraftDialog = () => {
this.setState({localDraftDialog: false});
};
clearTimer = () => {
clearTimeout(this.timer);
this.timer = null;
@@ -279,16 +229,13 @@ class MarkdownEditor extends React.Component {
// Goto rich edit page
// First, the user has the relevant permissions, otherwise he can only enter the viewer interface or cannot access
// case1: If file is draft file
// case2: If mode == 'edit' and the file has no draft
// case3: The length of markDownContent is 1 when clear all content in editor and the file has no draft
const { fileInfo } = this.state;
this.setState({
loading: false,
fileInfo: {...fileInfo, mtime, size, starred, permission, lastModifier, id},
markdownContent,
value: '',
readOnly: !hasPermission || hasDraft,
readOnly: !hasPermission,
});
if (userInfo && this.socket) {
@@ -309,7 +256,6 @@ class MarkdownEditor extends React.Component {
},
});
}
this.checkDraft();
this.listFileTags();
this.listFileParticipants();
@@ -480,9 +426,6 @@ class MarkdownEditor extends React.Component {
return (
<Fragment>
<HeaderToolbar
isDocs={isDocs}
hasDraft={hasDraft}
isDraft={isDraft}
editorApi={editorApi}
collabUsers={this.state.collabUsers}
fileInfo={this.state.fileInfo}
@@ -490,7 +433,6 @@ class MarkdownEditor extends React.Component {
openDialogs={this.openDialogs}
toggleShareLinkDialog={this.toggleShareLinkDialog}
onEdit={this.setEditorMode}
toggleNewDraft={editorApi.createDraftFile}
showFileHistory={this.state.isShowHistory ? false : true }
toggleHistory={this.toggleHistory}
readOnly={this.state.readOnly}
@@ -498,7 +440,6 @@ class MarkdownEditor extends React.Component {
contentChanged={this.state.contentChanged}
saving={this.state.saving}
onSaveEditorContent={this.onSaveEditorContent}
showDraftSaved={this.state.showDraftSaved}
isLocked={this.state.isLocked}
lockedByMe={this.state.lockedByMe}
toggleLockFile={this.toggleLockFile}

View File

@@ -1,125 +0,0 @@
/* eslint-disable linebreak-style */
import React from 'react';
import PropTypes from 'prop-types';
import Loading from '../../components/loading';
import moment from 'moment';
import { seafileAPI } from '../../utils/seafile-api';
import { draftRepoID, draftFilePath } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import toaster from '../../components/toast';
import '../../css/file-history.css';
moment.locale(window.app.config.lang);
class HistoryList extends React.Component {
constructor(props) {
super(props);
this.perPage = 25;
this.state = {
currentPage: 1,
loading: false
};
}
onClick = (event, key, preItem, currentItem)=> {
if (key === this.state.activeItem) return false;
this.props.onHistoryItemClick(currentItem, preItem, key);
};
onScroll = (event) => {
const clientHeight = event.target.clientHeight;
const scrollHeight = event.target.scrollHeight;
const scrollTop = event.target.scrollTop;
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (isBottom) {
if (this.props.totalReversionCount > this.perPage * this.state.currentPage) {
let currentPage = this.state.currentPage + 1;
this.setState({
currentPage: currentPage,
loading : true
});
seafileAPI.listFileHistoryRecords(draftRepoID, draftFilePath, currentPage, this.perPage).then((res) => {
let currentHistoryList = Object.assign([], this.props.historyList);
this.props.onHistoryListChange([...currentHistoryList, ...res.data.data]);
this.setState({
loading : false
});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
}
};
render() {
return (
<div className="history-body">
<ul onScroll={this.onScroll} className={'history-list-container'}>
{
this.props.historyList ?
this.props.historyList.map((item, index = 0, arr) => {
let preItemIndex = index + 1;
if (preItemIndex === arr.length) {
preItemIndex = index;
}
return (
<HistoryItem
onClick={this.onClick}
ctime={item.ctime}
className={this.props.activeItem === index ? 'item-active': ''}
name={item.creator_name}
index={index}
key={index}
preItem={arr[preItemIndex]}
currentItem={item}
/>
);
}) : <Loading/>
}
{
this.state.loading &&
<li className={'reloading-reversion'}><Loading /></li>
}
</ul>
</div>
);
}
}
class HistoryItem extends React.Component {
render() {
let time = moment.parseZone(this.props.ctime).format('YYYY-MM-DD HH:mm');
return (
<li onClick={(event) => this.props.onClick(event, this.props.index, this.props.preItem, this.props.currentItem)} className={'history-list-item ' + this.props.className}>
<div className="history-info">
<div className="time">{time}</div>
<div className="owner"><i className="squire-icon"/><span>{this.props.name}</span></div>
</div>
</li>
);
}
}
HistoryItem.propTypes = {
index: PropTypes.number.isRequired,
currentItem: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired,
ctime: PropTypes.string.isRequired,
className: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
preItem: PropTypes.string.isRequired,
};
HistoryList.propTypes = {
historyList: PropTypes.array.isRequired,
onHistoryItemClick: PropTypes.func.isRequired,
onHistoryListChange: PropTypes.func.isRequired,
totalReversionCount: PropTypes.number.isRequired,
activeItem: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
};
export default HistoryList;

View File

@@ -17,7 +17,6 @@ const propTypes = {
direntList: PropTypes.array.isRequired,
dirPath: PropTypes.string.isRequired,
toggleStar: PropTypes.func.isRequired,
unmarkDraft: PropTypes.func.isRequired,
onNewNotification: PropTypes.func.isRequired,
onClearNotification: PropTypes.func.isRequired
};
@@ -39,7 +38,6 @@ class ExternalOperations extends React.Component {
const eventBus = EventBus.getInstance();
this.unsubscribeInternalLinkEvent = eventBus.subscribe(EXTERNAL_EVENT.INTERNAL_LINK_CLICK, this.onInternalLinkToggle);
this.unsubscribeStar = eventBus.subscribe(EXTERNAL_EVENT.TOGGLE_STAR, this.toggleStar);
this.unsubscribeUnmark = eventBus.subscribe(EXTERNAL_EVENT.UNMARK_AS_DRAFT, this.unmark);
this.unsubscribeShare = eventBus.subscribe(EXTERNAL_EVENT.SHARE_SDOC, this.onShareToggle);
this.unsubscribeFreezeDocument = eventBus.subscribe(EXTERNAL_EVENT.FREEZE_DOCUMENT, this.onFreezeDocument);
this.unsubscribeUnfreeze = eventBus.subscribe(EXTERNAL_EVENT.UNFREEZE, this.unFreeze);
@@ -67,16 +65,6 @@ class ExternalOperations extends React.Component {
this.setState({ isShowInternalLinkDialog: !this.state.isShowInternalLinkDialog });
};
unmark = () => {
const { repoID, docPath } = this.props;
seafileAPI.sdocUnmarkAsDraft(repoID, docPath).then((res) => {
this.props.unmarkDraft();
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
toggleStar = () => {
const { isStarred, repoID, docPath } = this.props;
if (isStarred) {
@@ -147,9 +135,9 @@ class ExternalOperations extends React.Component {
return isDuplicated;
};
onAddFile = (filePath, isMarkdownDraft) => {
onAddFile = (filePath) => {
let repoID = this.props.repoID;
seafileAPI.createFile(repoID, filePath, isMarkdownDraft).then((res) => {
seafileAPI.createFile(repoID, filePath).then((res) => {
const eventBus = EventBus.getInstance();
eventBus.dispatch(EXTERNAL_EVENT.INSERT_LINK, { data: res.data });
}).catch((error) => {

View File

@@ -26,10 +26,6 @@ export default class SdocEditor extends React.Component {
this.setState({ isStarred: isStarred });
};
unmarkDraft = () => {
this.setState({ isDraft: false });
};
onSetFavicon = (suffix) => {
let { docName } = window.seafile;
if (suffix) {
@@ -89,7 +85,6 @@ export default class SdocEditor extends React.Component {
direntList={direntList}
dirPath={dirPath}
toggleStar={this.toggleStar}
unmarkDraft={this.unmarkDraft}
onNewNotification={this.onNewNotification}
onClearNotification={this.onClearNotification}
/>

View File

@@ -131,21 +131,6 @@ export const useNewAPI = window.fileHistory ? window.fileHistory.pageOptions.use
export const canDownload = window.fileHistory ? window.fileHistory.pageOptions.can_download_file : '';
export const canCompare = window.fileHistory ? window.fileHistory.pageOptions.can_compare : '';
// Draft review
export const draftFilePath = window.draft ? window.draft.config.draftFilePath: '';
export const draftOriginFilePath = window.draft ? window.draft.config.draftOriginFilePath: '';
export const draftFileName = window.draft ? window.draft.config.draftFileName: '';
export const draftID = window.draft ? window.draft.config.draftID : '';
export const draftRepoID = window.draft ? window.draft.config.draftRepoID : '';
export const author = window.draft ? window.draft.config.author : '';
export const authorAvatar = window.draft ? window.draft.config.authorAvatar : '';
export const originFileExists = window.draft ? window.draft.config.originFileExists : '';
export const draftFileExists = window.draft ? window.draft.config.draftFileExists : '';
export const draftStatus = window.draft ? window.draft.config.draftStatus : '';
export const draftPublishVersion = window.draft ? window.draft.config.draftPublishVersion : '';
export const originFileVersion = window.draft ? window.draft.config.originFileVersion : '';
export const filePermission = window.draft ? window.draft.config.perm : '';
// org admin
export const orgID = window.org ? window.org.pageOptions.orgID : '';
export const orgName = window.org ? window.org.pageOptions.orgName : '';

View File

@@ -38,10 +38,6 @@ class EditorUtilities {
});
}
createFile(filePath, isDraft) {
return seafileAPI.createFile(repoID, filePath, isDraft);
}
deleteFile(filePath) {
return seafileAPI.deleteFile(repoID, filePath);
}
@@ -95,18 +91,6 @@ class EditorUtilities {
return seafileAPI.revertFile(historyRepoID, filePath, commitID);
}
listDrafts() {
return seafileAPI.listDrafts();
}
deleteDraft(id) {
return seafileAPI.deleteDraft(id);
}
publishDraft(id) {
return seafileAPI.publishDraft(id);
}
zipDownload(parent_dir, dirents) {
return seafileAPI.zipDownload(repoID, parent_dir, dirents);
}

View File

@@ -27,8 +27,6 @@ const TextTranslation = {
'CONVERT_TO_SDOC' : {key : 'Convert to sdoc', value : gettext('Convert to sdoc')},
'CONVERT_TO_DOCX' : {key : 'Convert to docx', value : gettext('Convert to docx')},
'EXPORT_DOCX' : {key : 'Export docx', value : gettext('Export as docx')},
'MARK_AS_DRAFT' : {key : 'Mark as draft', value : gettext('Mark as draft')},
'UNMARK_AS_DRAFT' : {key : 'Unmark as draft', value : gettext('Unmark as draft')},
'HISTORY' : {key : 'History', value : gettext('History')},
'ACCESS_LOG' : {key : 'Access Log', value : gettext('Access Log')},
'PROPERTIES' : {key : 'Properties', value : gettext('Properties')},

View File

@@ -20,9 +20,6 @@ class URLDecorator {
case 'open_via_client':
url = 'seafile://openfile?repo_id=' + options.repoID + '&path=' + Utils.encodePath(options.filePath);
break;
case 'draft_view':
url = siteRoot + 'lib/' + options.repoID + '/file' + options.filePath + '?mode=edit&draft_id=' + options.draftId;
break;
default:
url = '';
break;

View File

@@ -620,15 +620,6 @@ export const Utils = {
}
if (permission == 'rw') {
/*
if (Utils.isSdocFile(dirent.name)) {
if (dirent.is_sdoc_draft) {
list.push(UNMARK_AS_DRAFT);
} else {
list.push(MARK_AS_DRAFT);
}
}
*/
list.push('Divider');
list.push(PROPERTIES, HISTORY);
if (isPro && fileAuditEnabled) {