Merge master

This commit is contained in:
Tom Moor
2017-09-13 19:18:49 -07:00
27 changed files with 581 additions and 144 deletions

View File

@@ -2,13 +2,21 @@
import React, { Component } from 'react';
import get from 'lodash/get';
import styled from 'styled-components';
import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
import { withRouter, Prompt } from 'react-router';
import keydown from 'react-keydown';
import Flex from 'components/Flex';
import { color, layout } from 'styles/constants';
import { collectionUrl } from 'utils/routeHelpers';
import {
collectionUrl,
updateDocumentUrl,
matchDocumentEdit,
matchDocumentMove,
} from 'utils/routeHelpers';
import Document from 'models/Document';
import DocumentMove from './components/DocumentMove';
import UiStore from 'stores/UiStore';
import DocumentsStore from 'stores/DocumentsStore';
import DocumentMenu from 'menus/DocumentMenu';
@@ -39,17 +47,16 @@ type Props = {
@observer class DocumentScene extends Component {
props: Props;
savedTimeout: number;
state: {
newDocument?: Document,
};
state = {
isDragging: false,
isLoading: false,
isSaving: false,
newDocument: undefined,
showAsSaved: false,
notFound: false,
};
@observable editCache: ?string;
@observable newDocument: ?Document;
@observable isDragging = false;
@observable isLoading = false;
@observable isSaving = false;
@observable showAsSaved = false;
@observable notFound = false;
@observable moveModalOpen: boolean = false;
componentDidMount() {
this.loadDocument(this.props);
@@ -60,7 +67,7 @@ type Props = {
nextProps.match.params.documentSlug !==
this.props.match.params.documentSlug
) {
this.setState({ notFound: false });
this.notFound = false;
this.loadDocument(nextProps);
}
}
@@ -70,6 +77,12 @@ type Props = {
this.props.ui.clearActiveDocument();
}
@keydown('m')
goToMove(event) {
event.preventDefault();
if (this.document) this.props.history.push(`${this.document.url}/move`);
}
loadDocument = async props => {
if (props.newDocument) {
const newDocument = new Document({
@@ -77,7 +90,7 @@ type Props = {
title: '',
text: '',
});
this.setState({ newDocument });
this.newDocument = newDocument;
} else {
let document = this.document;
if (document) {
@@ -89,16 +102,23 @@ type Props = {
if (document) {
this.props.ui.setActiveDocument(document);
// Cache data if user enters edit mode and cancels
this.editCache = document.text;
document.view();
// Update url to match the current one
this.props.history.replace(
updateDocumentUrl(this.props.match.url, document.url)
);
} else {
// Render 404 with search
this.setState({ notFound: true });
this.notFound = true;
}
}
};
get document() {
if (this.state.newDocument) return this.state.newDocument;
if (this.newDocument) return this.newDocument;
return this.props.documents.getByUrl(
`/doc/${this.props.match.params.documentSlug}`
);
@@ -115,36 +135,38 @@ type Props = {
this.props.history.push(`${this.document.collection.url}/new`);
};
handleCloseMoveModal = () => (this.moveModalOpen = false);
handleOpenMoveModal = () => (this.moveModalOpen = true);
onSave = async (redirect: boolean = false) => {
if (this.document && !this.document.allowSave) return;
let document = this.document;
if (!document) return;
this.setState({ isLoading: true, isSaving: true });
this.isLoading = true;
this.isSaving = true;
document = await document.save();
this.setState({ isLoading: false });
this.isLoading = false;
if (redirect || this.props.newDocument) {
this.props.history.push(document.url);
} else {
this.showAsSaved();
this.toggleShowAsSaved();
}
};
showAsSaved() {
this.setState({ showAsSaved: true, isSaving: false });
this.savedTimeout = setTimeout(
() => this.setState({ showAsSaved: false }),
2000
);
toggleShowAsSaved() {
this.showAsSaved = true;
this.isSaving = false;
this.savedTimeout = setTimeout(() => (this.showAsSaved = false), 2000);
}
onImageUploadStart = () => {
this.setState({ isLoading: true });
this.isLoading = true;
};
onImageUploadStop = () => {
this.setState({ isLoading: false });
this.isLoading = false;
};
onChange = text => {
@@ -156,6 +178,7 @@ type Props = {
let url;
if (this.document && this.document.url) {
url = this.document.url;
if (this.editCache) this.document.updateData({ text: this.editCache });
} else {
url = collectionUrl(this.props.match.params.id);
}
@@ -163,11 +186,11 @@ type Props = {
};
onStartDragging = () => {
this.setState({ isDragging: true });
this.isDragging = true;
};
onStopDragging = () => {
this.setState({ isDragging: false });
this.isDragging = false;
};
renderNotFound() {
@@ -176,23 +199,26 @@ type Props = {
render() {
const isNew = this.props.newDocument;
const isEditing = !!this.props.match.params.edit || isNew;
const isMoving = this.props.match.path === matchDocumentMove;
const isEditing = this.props.match.path === matchDocumentEdit || isNew;
const isFetching = !this.document;
const titleText = get(this.document, 'title', '');
const document = this.document;
if (this.state.notFound) {
if (this.notFound) {
return this.renderNotFound();
}
return (
<Container column auto>
{this.state.isDragging &&
{isMoving && document && <DocumentMove document={document} />}
{this.isDragging &&
<DropHere align="center" justify="center">
Drop files here to import into Atlas.
</DropHere>}
{titleText && <PageTitle title={titleText} />}
{this.state.isLoading && <LoadingIndicator />}
{this.isLoading && <LoadingIndicator />}
{isFetching &&
<CenteredContent>
<LoadingState />
@@ -231,11 +257,11 @@ type Props = {
<HeaderAction>
{isEditing
? <SaveAction
isSaving={this.state.isSaving}
isSaving={this.isSaving}
onClick={this.onSave.bind(this, true)}
disabled={
!(this.document && this.document.allowSave) ||
this.state.isSaving
this.isSaving
}
isNew={!!isNew}
/>