feat: Clicking the last updated time should open document history sidebar
Ref #1285
This commit is contained in:
parent
7abe375b3e
commit
810dc5a061
@ -1,39 +1,123 @@
|
||||
// @flow
|
||||
import { inject } from "mobx-react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import ViewsStore from "stores/ViewsStore";
|
||||
import AuthStore from "stores/AuthStore";
|
||||
import CollectionsStore from "stores/CollectionsStore";
|
||||
import Document from "models/Document";
|
||||
import PublishingInfo from "components/PublishingInfo";
|
||||
import Breadcrumb from "components/Breadcrumb";
|
||||
import Flex from "components/Flex";
|
||||
import Time from "components/Time";
|
||||
|
||||
type Props = {|
|
||||
views: ViewsStore,
|
||||
const Container = styled(Flex)`
|
||||
color: ${(props) => props.theme.textTertiary};
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const Modified = styled.span`
|
||||
color: ${(props) =>
|
||||
props.highlight ? props.theme.text : props.theme.textTertiary};
|
||||
font-weight: ${(props) => (props.highlight ? "600" : "400")};
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
collections: CollectionsStore,
|
||||
auth: AuthStore,
|
||||
showCollection?: boolean,
|
||||
showPublished?: boolean,
|
||||
document: Document,
|
||||
isDraft: boolean,
|
||||
|};
|
||||
children: React.Node,
|
||||
to?: string,
|
||||
};
|
||||
|
||||
function DocumentMeta({ views, isDraft, document }: Props) {
|
||||
const totalViews = views.countForDocument(document.id);
|
||||
function DocumentMeta({
|
||||
auth,
|
||||
collections,
|
||||
showPublished,
|
||||
showCollection,
|
||||
document,
|
||||
children,
|
||||
to,
|
||||
...rest
|
||||
}: Props) {
|
||||
const {
|
||||
modifiedSinceViewed,
|
||||
updatedAt,
|
||||
updatedBy,
|
||||
createdAt,
|
||||
publishedAt,
|
||||
archivedAt,
|
||||
deletedAt,
|
||||
isDraft,
|
||||
} = document;
|
||||
|
||||
// Prevent meta information from displaying if updatedBy is not available.
|
||||
// Currently the situation where this is true is rendering share links.
|
||||
if (!updatedBy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let content;
|
||||
|
||||
if (deletedAt) {
|
||||
content = (
|
||||
<span>
|
||||
deleted <Time dateTime={deletedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (archivedAt) {
|
||||
content = (
|
||||
<span>
|
||||
archived <Time dateTime={archivedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (createdAt === updatedAt) {
|
||||
content = (
|
||||
<span>
|
||||
created <Time dateTime={updatedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (publishedAt && (publishedAt === updatedAt || showPublished)) {
|
||||
content = (
|
||||
<span>
|
||||
published <Time dateTime={publishedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (isDraft) {
|
||||
content = (
|
||||
<span>
|
||||
saved <Time dateTime={updatedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<Modified highlight={modifiedSinceViewed}>
|
||||
updated <Time dateTime={updatedAt} /> ago
|
||||
</Modified>
|
||||
);
|
||||
}
|
||||
|
||||
const collection = collections.get(document.collectionId);
|
||||
const updatedByMe = auth.user && auth.user.id === updatedBy.id;
|
||||
|
||||
return (
|
||||
<Meta document={document}>
|
||||
{totalViews && !isDraft ? (
|
||||
<>
|
||||
· Viewed{" "}
|
||||
{totalViews === 1 ? "once" : `${totalViews} times`}
|
||||
</>
|
||||
) : null}
|
||||
</Meta>
|
||||
<Container align="center" {...rest}>
|
||||
{updatedByMe ? "You" : updatedBy.name}
|
||||
{to ? <Link to={to}>{content}</Link> : content}
|
||||
{showCollection && collection && (
|
||||
<span>
|
||||
in
|
||||
<strong>
|
||||
<Breadcrumb document={document} onlyText />
|
||||
</strong>
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
const Meta = styled(PublishingInfo)`
|
||||
margin: -12px 0 2em 0;
|
||||
font-size: 14px;
|
||||
|
||||
@media print {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
export default inject("views")(DocumentMeta);
|
||||
export default inject("collections", "auth")(observer(DocumentMeta));
|
||||
|
48
app/components/DocumentMetaWithViews.js
Normal file
48
app/components/DocumentMetaWithViews.js
Normal file
@ -0,0 +1,48 @@
|
||||
// @flow
|
||||
import { inject } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import ViewsStore from "stores/ViewsStore";
|
||||
import Document from "models/Document";
|
||||
import DocumentMeta from "components/DocumentMeta";
|
||||
|
||||
type Props = {|
|
||||
views: ViewsStore,
|
||||
document: Document,
|
||||
isDraft: boolean,
|
||||
to?: string,
|
||||
|};
|
||||
|
||||
function DocumentMetaWithViews({ views, to, isDraft, document }: Props) {
|
||||
const totalViews = views.countForDocument(document.id);
|
||||
|
||||
return (
|
||||
<Meta document={document} to={to}>
|
||||
{totalViews && !isDraft ? (
|
||||
<>
|
||||
· Viewed{" "}
|
||||
{totalViews === 1 ? "once" : `${totalViews} times`}
|
||||
</>
|
||||
) : null}
|
||||
</Meta>
|
||||
);
|
||||
}
|
||||
|
||||
const Meta = styled(DocumentMeta)`
|
||||
margin: -12px 0 2em 0;
|
||||
font-size: 14px;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
export default inject("views")(DocumentMetaWithViews);
|
@ -7,9 +7,9 @@ import styled, { withTheme } from "styled-components";
|
||||
import Document from "models/Document";
|
||||
import Badge from "components/Badge";
|
||||
import Button from "components/Button";
|
||||
import DocumentMeta from "components/DocumentMeta";
|
||||
import Flex from "components/Flex";
|
||||
import Highlight from "components/Highlight";
|
||||
import PublishingInfo from "components/PublishingInfo";
|
||||
import Tooltip from "components/Tooltip";
|
||||
import DocumentMenu from "menus/DocumentMenu";
|
||||
import { newDocumentUrl } from "utils/routeHelpers";
|
||||
@ -129,7 +129,7 @@ class DocumentPreview extends React.Component<Props> {
|
||||
processResult={this.replaceResultMarks}
|
||||
/>
|
||||
)}
|
||||
<PublishingInfo
|
||||
<DocumentMeta
|
||||
document={document}
|
||||
showCollection={showCollection}
|
||||
showPublished={showPublished}
|
||||
|
@ -5,7 +5,7 @@ import { Link } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { parseDocumentSlugFromUrl } from "shared/utils/parseDocumentIds";
|
||||
import DocumentsStore from "stores/DocumentsStore";
|
||||
import DocumentMeta from "components/DocumentMeta";
|
||||
import DocumentMetaWithViews from "components/DocumentMetaWithViews";
|
||||
import Editor from "components/Editor";
|
||||
|
||||
type Props = {
|
||||
@ -27,7 +27,7 @@ function HoverPreviewDocument({ url, documents, children }: Props) {
|
||||
return children(
|
||||
<Content to={document.url}>
|
||||
<Heading>{document.titleWithDefault}</Heading>
|
||||
<DocumentMeta isDraft={document.isDraft} document={document} />
|
||||
<DocumentMetaWithViews isDraft={document.isDraft} document={document} />
|
||||
|
||||
<Editor
|
||||
key={document.id}
|
||||
|
@ -1,120 +0,0 @@
|
||||
// @flow
|
||||
import { inject, observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import AuthStore from "stores/AuthStore";
|
||||
import CollectionsStore from "stores/CollectionsStore";
|
||||
import Document from "models/Document";
|
||||
import Breadcrumb from "components/Breadcrumb";
|
||||
import Flex from "components/Flex";
|
||||
import Time from "components/Time";
|
||||
|
||||
const Container = styled(Flex)`
|
||||
color: ${(props) => props.theme.textTertiary};
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const Modified = styled.span`
|
||||
color: ${(props) =>
|
||||
props.highlight ? props.theme.text : props.theme.textTertiary};
|
||||
font-weight: ${(props) => (props.highlight ? "600" : "400")};
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
collections: CollectionsStore,
|
||||
auth: AuthStore,
|
||||
showCollection?: boolean,
|
||||
showPublished?: boolean,
|
||||
document: Document,
|
||||
children: React.Node,
|
||||
};
|
||||
|
||||
function PublishingInfo({
|
||||
auth,
|
||||
collections,
|
||||
showPublished,
|
||||
showCollection,
|
||||
document,
|
||||
children,
|
||||
...rest
|
||||
}: Props) {
|
||||
const {
|
||||
modifiedSinceViewed,
|
||||
updatedAt,
|
||||
updatedBy,
|
||||
createdAt,
|
||||
publishedAt,
|
||||
archivedAt,
|
||||
deletedAt,
|
||||
isDraft,
|
||||
} = document;
|
||||
|
||||
// Prevent meta information from displaying if updatedBy is not available.
|
||||
// Currently the situation where this is true is rendering share links.
|
||||
if (!updatedBy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let content;
|
||||
|
||||
if (deletedAt) {
|
||||
content = (
|
||||
<span>
|
||||
deleted <Time dateTime={deletedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (archivedAt) {
|
||||
content = (
|
||||
<span>
|
||||
archived <Time dateTime={archivedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (createdAt === updatedAt) {
|
||||
content = (
|
||||
<span>
|
||||
created <Time dateTime={updatedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (publishedAt && (publishedAt === updatedAt || showPublished)) {
|
||||
content = (
|
||||
<span>
|
||||
published <Time dateTime={publishedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else if (isDraft) {
|
||||
content = (
|
||||
<span>
|
||||
saved <Time dateTime={updatedAt} /> ago
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<Modified highlight={modifiedSinceViewed}>
|
||||
updated <Time dateTime={updatedAt} /> ago
|
||||
</Modified>
|
||||
);
|
||||
}
|
||||
|
||||
const collection = collections.get(document.collectionId);
|
||||
const updatedByMe = auth.user && auth.user.id === updatedBy.id;
|
||||
|
||||
return (
|
||||
<Container align="center" {...rest}>
|
||||
{updatedByMe ? "You" : updatedBy.name}
|
||||
{content}
|
||||
{showCollection && collection && (
|
||||
<span>
|
||||
in
|
||||
<strong>
|
||||
<Breadcrumb document={document} onlyText />
|
||||
</strong>
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default inject("collections", "auth")(observer(PublishingInfo));
|
@ -8,10 +8,11 @@ import styled from "styled-components";
|
||||
import parseTitle from "shared/utils/parseTitle";
|
||||
import Document from "models/Document";
|
||||
import ClickablePadding from "components/ClickablePadding";
|
||||
import DocumentMeta from "components/DocumentMeta";
|
||||
import DocumentMetaWithViews from "components/DocumentMetaWithViews";
|
||||
import Editor from "components/Editor";
|
||||
import Flex from "components/Flex";
|
||||
import HoverPreview from "components/HoverPreview";
|
||||
import { documentHistoryUrl } from "utils/routeHelpers";
|
||||
|
||||
type Props = {
|
||||
onChangeTitle: (event: SyntheticInputEvent<>) => void,
|
||||
@ -88,7 +89,11 @@ class DocumentEditor extends React.Component<Props> {
|
||||
autoFocus={!title}
|
||||
maxLength={100}
|
||||
/>
|
||||
<DocumentMeta isDraft={isDraft} document={document} />
|
||||
<DocumentMetaWithViews
|
||||
isDraft={isDraft}
|
||||
document={document}
|
||||
to={documentHistoryUrl(document)}
|
||||
/>
|
||||
<Editor
|
||||
ref={this.editor}
|
||||
autoFocus={title && !this.props.defaultValue}
|
||||
|
@ -4,7 +4,7 @@ import * as React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import Document from "models/Document";
|
||||
import PublishingInfo from "components/PublishingInfo";
|
||||
import DocumentMeta from "components/DocumentMeta";
|
||||
import type { NavigationNode } from "types";
|
||||
|
||||
type Props = {
|
||||
@ -60,7 +60,7 @@ class ReferenceListItem extends React.Component<Props> {
|
||||
>
|
||||
<Title>{document.title}</Title>
|
||||
{document.updatedBy && (
|
||||
<PublishingInfo document={document} showCollection={showCollection} />
|
||||
<DocumentMeta document={document} showCollection={showCollection} />
|
||||
)}
|
||||
</DocumentLink>
|
||||
);
|
||||
|
Reference in New Issue
Block a user