Publishing Info (#70)
* Restore publishing info Closes #68 * Prevent document remounting / refetching when changing between edit / read * Merge master
This commit is contained in:
@ -98,7 +98,7 @@ export default class MarkdownEditor extends Component {
|
|||||||
|
|
||||||
render = () => {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<span className={styles.container}>
|
<span>
|
||||||
<ClickablePadding onClick={this.focusAtStart} />
|
<ClickablePadding onClick={this.focusAtStart} />
|
||||||
<Toolbar state={this.state.state} onChange={this.onChange} />
|
<Toolbar state={this.state.state} onChange={this.onChange} />
|
||||||
<Editor
|
<Editor
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1em;
|
|
||||||
line-height: 1.5em;
|
|
||||||
|
|
||||||
padding: 0 3em;
|
|
||||||
max-width: 50em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
color: #1b2631;
|
color: #1b2631;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
@ -92,10 +92,7 @@ type Props = {
|
|||||||
<Flex>
|
<Flex>
|
||||||
<Link to="/search">
|
<Link to="/search">
|
||||||
<div className={styles.search} title="Search (/)">
|
<div className={styles.search} title="Search (/)">
|
||||||
<img
|
<img src={searchIcon} alt="Search" />
|
||||||
src={searchIcon}
|
|
||||||
alt="Search"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>}
|
</Flex>}
|
||||||
|
@ -1,36 +1,47 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React, { PropTypes } from 'react';
|
import React, { Component } from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import type { User } from 'types';
|
||||||
import { Flex } from 'reflexbox';
|
import { Flex } from 'reflexbox';
|
||||||
|
|
||||||
import styles from './PublishingInfo.scss';
|
const Container = styled(Flex)`
|
||||||
|
margin-bottom: 30px;
|
||||||
|
color: #ccc;
|
||||||
|
font-size: 13px;
|
||||||
|
`;
|
||||||
|
|
||||||
class PublishingInfo extends React.Component {
|
const Avatars = styled(Flex)`
|
||||||
static propTypes = {
|
flex-direction: row-reverse;
|
||||||
collaborators: PropTypes.array.isRequired,
|
margin-right: 10px;
|
||||||
createdAt: PropTypes.string.isRequired,
|
`;
|
||||||
createdBy: PropTypes.object.isRequired,
|
|
||||||
updatedAt: PropTypes.string.isRequired,
|
const Avatar = styled.img`
|
||||||
updatedBy: PropTypes.object.isRequired,
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid #FFFFFF;
|
||||||
|
`;
|
||||||
|
|
||||||
|
class PublishingInfo extends Component {
|
||||||
|
props: {
|
||||||
|
collaborators: Array<User>,
|
||||||
|
createdAt: string,
|
||||||
|
createdBy: User,
|
||||||
|
updatedAt: string,
|
||||||
|
updatedBy: User,
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Flex align="center" className={styles.user}>
|
<Container align="center">
|
||||||
<Flex className={styles.avatarLine}>
|
<Avatars>
|
||||||
{this.props.collaborators
|
{this.props.collaborators.map(user => (
|
||||||
.reverse()
|
<Avatar key={user.id} src={user.avatarUrl} title={user.name} />
|
||||||
.map(user => (
|
))}
|
||||||
<Avatar
|
</Avatars>
|
||||||
key={`avatar-${user.id}`}
|
<span>
|
||||||
src={user.avatarUrl}
|
|
||||||
title={user.name}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Flex>
|
|
||||||
<span className={styles.userName}>
|
|
||||||
{this.props.createdBy.name}
|
{this.props.createdBy.name}
|
||||||
{' '}
|
{' '}
|
||||||
published
|
published
|
||||||
@ -45,18 +56,9 @@ class PublishingInfo extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
: null}
|
: null}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Avatar = styled.img`
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
marginRight: '-12px',
|
|
||||||
|
|
||||||
border-radius: 50%;
|
|
||||||
border: '2px solid #FFFFFF';
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default PublishingInfo;
|
export default PublishingInfo;
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
.avatarLine {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
color: #ccc;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.userName {
|
|
||||||
margin: 0 0 0 10px;
|
|
||||||
}
|
|
@ -54,7 +54,6 @@ const KeyboardShortcuts = () => (
|
|||||||
<Flatpage title="Keyboard shortcuts" content={flatpages.keyboard} />
|
<Flatpage title="Keyboard shortcuts" content={flatpages.keyboard} />
|
||||||
);
|
);
|
||||||
const Api = () => <Flatpage title="API" content={flatpages.api} />;
|
const Api = () => <Flatpage title="API" content={flatpages.api} />;
|
||||||
const DocumentEdit = () => <Document editDocument />;
|
|
||||||
const DocumentNew = () => <Document newDocument />;
|
const DocumentNew = () => <Document newDocument />;
|
||||||
const DocumentNewChild = () => <Document newChildDocument />;
|
const DocumentNewChild = () => <Document newChildDocument />;
|
||||||
|
|
||||||
@ -70,7 +69,7 @@ render(
|
|||||||
<Route exact path="/dashboard" component={Dashboard} />
|
<Route exact path="/dashboard" component={Dashboard} />
|
||||||
<Route exact path="/collections/:id" component={Atlas} />
|
<Route exact path="/collections/:id" component={Atlas} />
|
||||||
<Route exact path="/d/:id" component={Document} />
|
<Route exact path="/d/:id" component={Document} />
|
||||||
<Route exact path="/d/:id/edit" component={DocumentEdit} />
|
<Route exact path="/d/:id/:edit" component={Document} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/collections/:id/new"
|
path="/collections/:id/new"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
|
import styled from 'styled-components';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { withRouter, Prompt } from 'react-router';
|
import { withRouter, Prompt } from 'react-router';
|
||||||
import { Flex } from 'reflexbox';
|
import { Flex } from 'reflexbox';
|
||||||
@ -10,6 +11,7 @@ import Breadcrumbs from './components/Breadcrumbs';
|
|||||||
import Menu from './components/Menu';
|
import Menu from './components/Menu';
|
||||||
import Editor from 'components/Editor';
|
import Editor from 'components/Editor';
|
||||||
import Layout, { HeaderAction, SaveAction } from 'components/Layout';
|
import Layout, { HeaderAction, SaveAction } from 'components/Layout';
|
||||||
|
import PublishingInfo from 'components/PublishingInfo';
|
||||||
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
|
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
|
||||||
import CenteredContent from 'components/CenteredContent';
|
import CenteredContent from 'components/CenteredContent';
|
||||||
|
|
||||||
@ -18,13 +20,25 @@ You have unsaved changes.
|
|||||||
Are you sure you want to discard them?
|
Are you sure you want to discard them?
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
position: relative;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
padding: 0 3em;
|
||||||
|
width: 50em;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Meta = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
`;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
match: Object,
|
match: Object,
|
||||||
history: Object,
|
history: Object,
|
||||||
keydown: Object,
|
keydown: Object,
|
||||||
editDocument?: boolean,
|
|
||||||
newChildDocument?: boolean,
|
newChildDocument?: boolean,
|
||||||
editDocument?: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@observer class Document extends Component {
|
@observer class Document extends Component {
|
||||||
@ -40,7 +54,7 @@ type Props = {
|
|||||||
if (this.props.newDocument) {
|
if (this.props.newDocument) {
|
||||||
this.store.collectionId = this.props.match.params.id;
|
this.store.collectionId = this.props.match.params.id;
|
||||||
this.store.newDocument = true;
|
this.store.newDocument = true;
|
||||||
} else if (this.props.editDocument) {
|
} else if (this.props.match.params.edit) {
|
||||||
this.store.documentId = this.props.match.params.id;
|
this.store.documentId = this.props.match.params.id;
|
||||||
this.store.fetchDocument();
|
this.store.fetchDocument();
|
||||||
} else if (this.props.newChildDocument) {
|
} else if (this.props.newChildDocument) {
|
||||||
@ -81,7 +95,7 @@ type Props = {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const isNew = this.props.newDocument || this.props.newChildDocument;
|
const isNew = this.props.newDocument || this.props.newChildDocument;
|
||||||
const isEditing = this.props.editDocument;
|
const isEditing = this.props.match.params.edit;
|
||||||
const title = (
|
const title = (
|
||||||
<Breadcrumbs
|
<Breadcrumbs
|
||||||
document={this.store.document}
|
document={this.store.document}
|
||||||
@ -127,15 +141,27 @@ type Props = {
|
|||||||
<AtlasPreviewLoading />
|
<AtlasPreviewLoading />
|
||||||
</CenteredContent>}
|
</CenteredContent>}
|
||||||
{this.store.document &&
|
{this.store.document &&
|
||||||
<Editor
|
<Container>
|
||||||
text={this.store.document.text}
|
{!isEditing &&
|
||||||
onImageUploadStart={this.onImageUploadStart}
|
<Meta>
|
||||||
onImageUploadStop={this.onImageUploadStop}
|
<PublishingInfo
|
||||||
onChange={this.store.updateText}
|
collaborators={this.store.document.collaborators}
|
||||||
onSave={this.onSave}
|
createdAt={this.store.document.createdAt}
|
||||||
onCancel={this.onCancel}
|
createdBy={this.store.document.createdBy}
|
||||||
readOnly={!this.props.editDocument}
|
updatedAt={this.store.document.updatedAt}
|
||||||
/>}
|
updatedBy={this.store.document.updatedBy}
|
||||||
|
/>
|
||||||
|
</Meta>}
|
||||||
|
<Editor
|
||||||
|
text={this.store.document.text}
|
||||||
|
onImageUploadStart={this.onImageUploadStart}
|
||||||
|
onImageUploadStop={this.onImageUploadStop}
|
||||||
|
onChange={this.store.updateText}
|
||||||
|
onSave={this.onSave}
|
||||||
|
onCancel={this.onCancel}
|
||||||
|
readOnly={!isEditing}
|
||||||
|
/>
|
||||||
|
</Container>}
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ export type Document = {
|
|||||||
collaborators: Array<User>,
|
collaborators: Array<User>,
|
||||||
collection: Object,
|
collection: Object,
|
||||||
createdAt: string,
|
createdAt: string,
|
||||||
createdBy: string,
|
createdBy: User,
|
||||||
html: string,
|
html: string,
|
||||||
id: string,
|
id: string,
|
||||||
private: boolean,
|
private: boolean,
|
||||||
@ -31,7 +31,7 @@ export type Document = {
|
|||||||
text: string,
|
text: string,
|
||||||
title: string,
|
title: string,
|
||||||
updatedAt: string,
|
updatedAt: string,
|
||||||
updatedBy: string,
|
updatedBy: User,
|
||||||
url: string,
|
url: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user