1
0
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:
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

@@ -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;