Document editing

This commit is contained in:
Jori Lallo
2016-05-25 21:26:06 -07:00
parent 814ed7b2da
commit 4c6964ad07
16 changed files with 261 additions and 52 deletions

View File

@@ -34,7 +34,7 @@ class Atlas extends React.Component {
let actions;
let title;
if (this.props.isLoading === false) {
if (!this.props.isLoading) {
actions = <Link to={ `/atlas/${atlas.id}/new` }>New document</Link>;
title = <Title>{ atlas.name }</Title>;
}

View File

@@ -0,0 +1,134 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {
resetEditor,
updateText,
updateTitle,
replaceText,
} from 'actions/EditorActions';
import {
resetDocument,
fetchDocumentAsync,
saveDocumentAsync,
} from 'actions/DocumentActions';
import Layout, { Title } from 'components/Layout';
import Flex from 'components/Flex';
import MarkdownEditor from 'components/MarkdownEditor';
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
import CenteredContent from 'components/CenteredContent';
import SaveAction from './components/SaveAction';
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,
}
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);
}
}
onSave = () => {
if (this.props.title.length === 0) {
alert("Please add a title before saving (hint: Write a markdown header)");
return
}
this.props.saveDocumentAsync(
null,
this.props.document.id,
this.props.title,
this.props.text,
)
}
render() {
let title = (
<Title
truncate={ 60 }
placeholder={ "Untitle document" }
>
{ this.props.title }
</Title>
);
return (
<Layout
actions={(
<Flex direction="row" align="center">
<SaveAction onClick={ this.onSave } />
</Flex>
)}
title={ title }
fixed={ true }
>
{ (this.props.isLoading && !this.props.document) ? (
<CenteredContent>
<AtlasPreviewLoading />
</CenteredContent>
) : (
<MarkdownEditor
onChange={ this.props.updateText }
text={ this.props.text }
replaceText={this.props.replaceText}
/>
) }
</Layout>
);
}
}
const mapStateToProps = (state) => {
return {
document: state.document.data,
text: state.editor.text,
title: state.editor.title,
isLoading: state.document.isLoading,
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
resetEditor,
updateText,
updateTitle,
replaceText,
resetDocument,
fetchDocumentAsync,
saveDocumentAsync,
}, dispatch)
};
DocumentEdit = connect(
mapStateToProps,
mapDispatchToProps,
)(DocumentEdit);
export default DocumentEdit;

View File

@@ -0,0 +1,23 @@
import React from 'react';
import { Arrow } from 'rebass';
class SaveAction extends React.Component {
propTypes = {
onClick: React.PropTypes.func.isRequired,
}
onClick = (event) => {
event.preventDefault();
this.props.onClick();
}
render() {
return (
<div>
<a href onClick={ this.onClick }>Save</a>
</div>
);
}
};
export default SaveAction;

View File

@@ -0,0 +1,2 @@
import DocumentEdit from './DocumentEdit';
export default DocumentEdit;

View File

@@ -1,5 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import Link from 'react-router/lib/Link';
import { bindActionCreators } from 'redux';
import { fetchDocumentAsync } from 'actions/DocumentActions';
@@ -19,13 +20,16 @@ class DocumentScene extends React.Component {
render() {
const document = this.props.document;
let title;
let actions;
if (document) {
actions = <Link to={ `/documents/${document.id}/edit` }>Edit</Link>;
title = `${document.atlas.name} - ${document.title}`;
}
return (
<Layout
title={ title }
actions={ actions }
>
<CenteredContent>
{ this.props.isLoading || !document ? (

View File

@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {
resetEditor,
updateText,
replaceText,
} from 'actions/EditorActions';
@@ -10,12 +11,11 @@ import {
saveDocumentAsync,
} from 'actions/DocumentActions';
import styles from './Editor.scss';
import 'assets/styles/codemirror.css';
import Layout, { Title } from 'components/Layout';
import Flex from 'components/Flex';
import MarkdownEditor from 'components/MarkdownEditor';
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
import CenteredContent from 'components/CenteredContent';
import SaveAction from './components/SaveAction';
import MoreAction from './components/MoreAction';
@@ -31,7 +31,9 @@ class Editor extends Component {
componentDidMount = () => {
const atlasId = this.props.routeParams.id;
this.setState({ atlasId: atlasId });
this.setState({
atlasId: atlasId,
});
}
onSave = () => {
@@ -88,6 +90,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
resetEditor,
updateText,
replaceText,
saveDocumentAsync,

View File

@@ -1,13 +0,0 @@
.container {
display: flex;
flex-flow: column;
width: 100%;
height: 100%;
background-color: #fff;
font-family: -apple-system, "Helvetica Neue", "Lucida Grande";
color: #222;
}
.content {
}