mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-20 02:48:51 +00:00
[draft] removed related code & files (#5993)
* [draft] removed related code & files * [draft] removed related code & files
This commit is contained in:
@@ -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;
|
@@ -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>
|
||||
|
@@ -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 (
|
||||
|
@@ -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;
|
@@ -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;
|
Reference in New Issue
Block a user