Merge master

This commit is contained in:
Tom Moor
2017-09-11 22:49:53 -07:00
55 changed files with 791 additions and 1183 deletions

View File

@@ -1,9 +1,11 @@
// @flow
import React from 'react';
import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
import styled from 'styled-components';
import DocumentsStore from 'stores/DocumentsStore';
import Flex from 'components/Flex';
import DocumentList from 'components/DocumentList';
import PageTitle from 'components/PageTitle';
import CenteredContent from 'components/CenteredContent';
@@ -26,29 +28,33 @@ type Props = {
@observer class Dashboard extends React.Component {
props: Props;
@observable isLoaded = false;
componentDidMount() {
this.props.documents.fetchAll();
this.props.documents.fetchRecentlyViewed();
this.loadContent();
}
get showPlaceholder() {
const { isLoaded, isFetching } = this.props.documents;
return !isLoaded && isFetching;
}
loadContent = async () => {
await Promise.all([
this.props.documents.fetchRecentlyModified({ limit: 5 }),
this.props.documents.fetchRecentlyViewed({ limit: 5 }),
]);
this.isLoaded = true;
};
render() {
return (
<CenteredContent>
<PageTitle title="Home" />
<h1>Home</h1>
<Subheading>Recently viewed</Subheading>
{this.showPlaceholder && <ListPlaceholder />}
<DocumentList documents={this.props.documents.recentlyViewed} />
<Subheading>Recently edited</Subheading>
<DocumentList documents={this.props.documents.recentlyEdited} />
{this.showPlaceholder && <ListPlaceholder />}
{this.isLoaded
? <Flex column>
<Subheading>Recently viewed</Subheading>
<DocumentList documents={this.props.documents.recentlyViewed} />
<Subheading>Recently edited</Subheading>
<DocumentList documents={this.props.documents.recentlyEdited} />
</Flex>
: <ListPlaceholder count={5} />}
</CenteredContent>
);
}

View File

@@ -6,6 +6,7 @@ import { observer, inject } from 'mobx-react';
import { withRouter, Prompt } from 'react-router';
import Flex from 'components/Flex';
import { color, layout } from 'styles/constants';
import { collectionUrl } from 'utils/routeHelpers';
import Document from 'models/Document';
import UiStore from 'stores/UiStore';
@@ -19,6 +20,7 @@ import LoadingIndicator from 'components/LoadingIndicator';
import Collaborators from 'components/Collaborators';
import CenteredContent from 'components/CenteredContent';
import PageTitle from 'components/PageTitle';
import Search from 'scenes/Search';
const DISCARD_CHANGES = `
You have unsaved changes.
@@ -46,6 +48,7 @@ type Props = {
isSaving: false,
newDocument: undefined,
showAsSaved: false,
notFound: false,
};
componentDidMount() {
@@ -57,6 +60,7 @@ type Props = {
nextProps.match.params.documentSlug !==
this.props.match.params.documentSlug
) {
this.setState({ notFound: false });
this.loadDocument(nextProps);
}
}
@@ -86,6 +90,9 @@ type Props = {
if (document) {
this.props.ui.setActiveDocument(document);
document.view();
} else {
// Render 404 with search
this.setState({ notFound: true });
}
}
};
@@ -146,7 +153,13 @@ type Props = {
};
onCancel = () => {
this.props.history.goBack();
let url;
if (this.document && this.document.url) {
url = this.document.url;
} else {
url = collectionUrl(this.props.match.params.id);
}
this.props.history.push(url);
};
onStartDragging = () => {
@@ -157,6 +170,10 @@ type Props = {
this.setState({ isDragging: false });
};
renderNotFound() {
return <Search notFound />;
}
render() {
const isNew = this.props.newDocument;
const isEditing = !!this.props.match.params.edit || isNew;
@@ -164,6 +181,10 @@ type Props = {
const titleText = get(this.document, 'title', '');
const document = this.document;
if (this.state.notFound) {
return this.renderNotFound();
}
return (
<Container column auto>
{this.state.isDragging &&

View File

@@ -26,9 +26,7 @@ type Props = {
if (state && state.nextPathname) {
sessionStorage.removeItem('redirectTo');
sessionStorage.setItem('redirectTo', state.nextPathname);
notifications.push(
<Alert key="login" info>Please login to continue</Alert>
);
notifications.push(<Alert key="login">Please login to continue</Alert>);
}
return notifications;

View File

@@ -1,48 +1,49 @@
// @flow
import React, { PropTypes } from 'react';
import React from 'react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import { color } from 'styles/constants';
import styles from './ApiKeyRow.scss';
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);
type Props = {
id: string,
name: ?string,
secret: string,
onDelete: Function,
};
class ApiKeyRow extends React.Component {
static propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
secret: PropTypes.string.isRequired,
onDelete: PropTypes.func.isRequired,
};
state = {
disabled: false,
};
@observer class ApiKeyRow extends React.Component {
props: Props;
@observable disabled: boolean;
onClick = () => {
this.props.onDelete(this.props.id);
this.setState({ disabled: true });
this.disabled = true;
};
render() {
const { name, secret } = this.props;
const { disabled } = this.state;
const { disabled } = this;
return (
<tr>
<td>{name}</td>
<td><code>{secret}</code></td>
<td>
<span
role="button"
onClick={this.onClick}
className={cx(styles.deleteAction, { disabled })}
>
Delete
</span>
<Action role="button" onClick={this.onClick} disabled={disabled}>
Action
</Action>
</td>
</tr>
);
}
}
const Action = styled.span`
font-size: 14px;
color: ${color.text};
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
`;
export default ApiKeyRow;

View File

@@ -1,10 +0,0 @@
@import '~styles/constants.scss';
.deleteAction {
font-size: 14px;
color: $textColor;
}
.disabled {
opacity: 0.5;
}