MobX based editing
This commit is contained in:
@@ -1,73 +1,45 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import {
|
||||
resetEditor,
|
||||
updateText,
|
||||
updateTitle,
|
||||
replaceText,
|
||||
} from 'actions/EditorActions';
|
||||
import {
|
||||
resetDocument,
|
||||
fetchDocumentAsync,
|
||||
saveDocumentAsync,
|
||||
} from 'actions/DocumentActions';
|
||||
import state from './DocumentEditState';
|
||||
|
||||
import Layout, { Title } from 'components/Layout';
|
||||
import Switch from 'components/Switch';
|
||||
import Layout, { Title, HeaderAction } from 'components/Layout';
|
||||
import Flex from 'components/Flex';
|
||||
import MarkdownEditor from 'components/MarkdownEditor';
|
||||
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
|
||||
|
||||
import SaveAction from './components/SaveAction';
|
||||
import Preview from './components/Preview';
|
||||
import EditorPane from './components/EditorPane';
|
||||
|
||||
import styles from './DocumentEdit.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
@observer
|
||||
class DocumentEdit extends Component {
|
||||
static propTypes = {
|
||||
updateText: React.PropTypes.func.isRequired,
|
||||
updateTitle: React.PropTypes.func.isRequired,
|
||||
replaceText: React.PropTypes.func.isRequired,
|
||||
resetDocument: React.PropTypes.func.isRequired,
|
||||
saveDocumentAsync: React.PropTypes.func.isRequired,
|
||||
text: React.PropTypes.string,
|
||||
title: React.PropTypes.string,
|
||||
isSaving: React.PropTypes.bool,
|
||||
}
|
||||
|
||||
state = {
|
||||
loadingDocument: false,
|
||||
}
|
||||
|
||||
componentWillMount = () => {
|
||||
this.props.resetEditor();
|
||||
this.props.resetDocument();
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const id = this.props.routeParams.id;
|
||||
this.props.fetchDocumentAsync(id);
|
||||
}
|
||||
|
||||
componentWillReceiveProps = (nextProps) => {
|
||||
if (!this.props.document && nextProps.document) {
|
||||
const doc = nextProps.document;
|
||||
this.props.updateText(doc.text);
|
||||
this.props.updateTitle(doc.title);
|
||||
}
|
||||
state.documentId = this.props.params.id;
|
||||
state.fetchDocument();
|
||||
}
|
||||
|
||||
onSave = () => {
|
||||
if (this.props.title.length === 0) {
|
||||
alert("Please add a title before saving (hint: Write a markdown header)");
|
||||
return
|
||||
}
|
||||
// if (this.props.title.length === 0) {
|
||||
// alert("Please add a title before saving (hint: Write a markdown header)");
|
||||
// return
|
||||
// }
|
||||
state.updateDocument();
|
||||
}
|
||||
|
||||
this.props.saveDocumentAsync(
|
||||
null,
|
||||
this.props.document.id,
|
||||
this.props.title,
|
||||
this.props.text,
|
||||
)
|
||||
state = {}
|
||||
|
||||
onScroll = (scrollTop) => {
|
||||
this.setState({
|
||||
scrollTop: scrollTop,
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -76,62 +48,60 @@ class DocumentEdit extends Component {
|
||||
truncate={ 60 }
|
||||
placeholder={ "Untitle document" }
|
||||
>
|
||||
{ this.props.title }
|
||||
{ state.title }
|
||||
</Title>
|
||||
);
|
||||
const actions = (
|
||||
<Flex direction="row">
|
||||
<HeaderAction>
|
||||
<SaveAction
|
||||
onClick={ this.onSave }
|
||||
disabled={ state.isSaving }
|
||||
/>
|
||||
</HeaderAction>
|
||||
<DropdownMenu label="More">
|
||||
<MenuItem onClick={ state.togglePreview }>
|
||||
Preview <Switch checked={ state.preview } />
|
||||
</MenuItem>
|
||||
</DropdownMenu>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout
|
||||
actions={(
|
||||
<Flex direction="row" align="center">
|
||||
<SaveAction onClick={ this.onSave } />
|
||||
</Flex>
|
||||
)}
|
||||
actions={ actions }
|
||||
title={ title }
|
||||
fixed={ true }
|
||||
loading={ this.props.isSaving }
|
||||
loading={ state.isSaving }
|
||||
>
|
||||
{ (this.props.isLoading && !this.props.document) ? (
|
||||
{ (state.isFetching) ? (
|
||||
<CenteredContent>
|
||||
<AtlasPreviewLoading />
|
||||
</CenteredContent>
|
||||
) : (
|
||||
<MarkdownEditor
|
||||
onChange={ this.props.updateText }
|
||||
text={ this.props.text }
|
||||
replaceText={this.props.replaceText}
|
||||
/>
|
||||
<div className={ styles.container }>
|
||||
<EditorPane
|
||||
fullWidth={ !state.preview }
|
||||
onScroll={ this.onScroll }
|
||||
>
|
||||
<MarkdownEditor
|
||||
onChange={ state.updateText }
|
||||
text={ state.text }
|
||||
replaceText={ state.replaceText }
|
||||
/>
|
||||
</EditorPane>
|
||||
{ state.preview ? (
|
||||
<EditorPane
|
||||
scrollTop={ this.state.scrollTop }
|
||||
>
|
||||
<Preview html={ state.htmlPreview } />
|
||||
</EditorPane>
|
||||
) : null }
|
||||
</div>
|
||||
) }
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
document: state.document.data,
|
||||
text: state.editor.text,
|
||||
title: state.editor.title,
|
||||
isLoading: state.document.isLoading,
|
||||
isSaving: state.document.isSaving,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
resetEditor,
|
||||
updateText,
|
||||
updateTitle,
|
||||
replaceText,
|
||||
resetDocument,
|
||||
fetchDocumentAsync,
|
||||
saveDocumentAsync,
|
||||
}, dispatch)
|
||||
};
|
||||
|
||||
DocumentEdit = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(DocumentEdit);
|
||||
|
||||
export default DocumentEdit;
|
||||
|
||||
Reference in New Issue
Block a user