This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
outline/app/components/DocumentPreview/DocumentPreview.js

197 lines
4.6 KiB
JavaScript
Raw Normal View History

2017-05-12 00:23:56 +00:00
// @flow
import * as React from "react";
import { observer } from "mobx-react";
import { Link } from "react-router-dom";
import { StarredIcon } from "outline-icons";
import styled, { withTheme } from "styled-components";
import Flex from "components/Flex";
import Badge from "components/Badge";
import Tooltip from "components/Tooltip";
import Highlight from "components/Highlight";
import PublishingInfo from "components/PublishingInfo";
import DocumentMenu from "menus/DocumentMenu";
import Document from "models/Document";
type Props = {
document: Document,
2017-07-09 18:26:17 +00:00
highlight?: ?string,
context?: ?string,
showCollection?: boolean,
showPublished?: boolean,
2019-04-09 04:47:27 +00:00
showPin?: boolean,
feat: Memberships (#1032) * WIP * feat: Add collection.memberships endpoint * feat: Add ability to filter collection.memberships with query * WIP * Merge stashed work * feat: Add ability to filter memberships by permission * continued refactoring * paginated list component * Collection member management * fix: Incorrect policy data sent down after collection.update * Reduce duplication, add empty state * cleanup * fix: Modal close should be a real button * fix: Allow opening edit from modal * fix: remove unused methods * test: fix * Passing test suite * Refactor * fix: Flow UI errors * test: Add collections.update tests * lint * test: moar tests * fix: Missing scopes, more missing tests * fix: Handle collection privacy change over socket * fix: More membership scopes * fix: view endpoint permissions * fix: respond to privacy change on socket event * policy driven menus * fix: share endpoint policies * chore: Use policies to drive documents UI * alignment * fix: Header height * fix: Correct behavior when collection becomes private * fix: Header height for read-only collection * send id's over socket instead of serialized objects * fix: Remote policy change * fix: reduce collection fetching * More websocket efficiencies * fix: Document collection pinning * fix: Restored ability to edit drafts fix: Removed ability to star drafts * fix: Require write permissions to pin doc to collection * fix: Header title overlaying document actions at small screen sizes * fix: Jank on load caused by previous commit * fix: Double collection fetch post-publish * fix: Hide publish button if draft is in no longer accessible collection * fix: Always allow deleting drafts fix: Improved handling of deleted documents * feat: Show collections in drafts view feat: Show more obvious 'draft' badge on documents * fix: incorrect policies after publish to private collection * fix: Duplicating a draft publishes it
2019-10-06 01:42:03 +00:00
showDraft?: boolean,
};
2018-06-10 02:10:30 +00:00
const StyledStar = withTheme(styled(({ solid, theme, ...props }) => (
2019-03-13 04:35:35 +00:00
<StarredIcon color={theme.text} {...props} />
2017-10-21 22:34:00 +00:00
))`
2018-07-25 04:13:54 +00:00
flex-shrink: 0;
opacity: ${props => (props.solid ? "1 !important" : 0)};
2017-10-01 23:00:18 +00:00
transition: all 100ms ease-in-out;
&:hover {
transform: scale(1.1);
}
&:active {
transform: scale(0.95);
}
2018-06-10 02:10:30 +00:00
`);
const StyledDocumentMenu = styled(DocumentMenu)`
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
`;
const DocumentLink = styled(Link)`
display: block;
margin: 10px -8px;
padding: 6px 8px;
border-radius: 8px;
max-height: 50vh;
min-width: 100%;
overflow: hidden;
position: relative;
${StyledDocumentMenu} {
opacity: 0;
}
&:hover,
&:active,
&:focus {
2019-03-13 04:35:35 +00:00
background: ${props => props.theme.listItemHoverBackground};
outline: none;
2017-09-03 01:43:12 +00:00
${StyledStar}, ${StyledDocumentMenu} {
2017-11-10 22:14:30 +00:00
opacity: 0.5;
2017-09-03 01:43:12 +00:00
&:hover {
opacity: 1;
}
}
}
`;
const Heading = styled.h3`
display: flex;
align-items: center;
height: 24px;
margin-top: 0;
margin-bottom: 0.25em;
2018-07-25 04:13:54 +00:00
overflow: hidden;
white-space: nowrap;
color: ${props => props.theme.text};
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
`;
const Actions = styled(Flex)`
margin-left: 4px;
align-items: center;
`;
2018-07-25 04:13:54 +00:00
const Title = styled(Highlight)`
max-width: 90%;
overflow: hidden;
text-overflow: ellipsis;
`;
const ResultContext = styled(Highlight)`
display: block;
2019-03-13 04:35:35 +00:00
color: ${props => props.theme.textTertiary};
font-size: 14px;
margin-top: -0.25em;
margin-bottom: 0.25em;
`;
const SEARCH_RESULT_REGEX = /<b\b[^>]*>(.*?)<\/b>/gi;
2017-11-10 22:14:30 +00:00
@observer
2018-05-05 23:16:08 +00:00
class DocumentPreview extends React.Component<Props> {
star = (ev: SyntheticEvent<>) => {
ev.preventDefault();
ev.stopPropagation();
this.props.document.star();
};
unstar = (ev: SyntheticEvent<>) => {
ev.preventDefault();
ev.stopPropagation();
this.props.document.unstar();
};
replaceResultMarks = (tag: string) => {
// don't use SEARCH_RESULT_REGEX here as it causes
// an infinite loop to trigger a regex inside it's own callback
return tag.replace(/<b\b[^>]*>(.*?)<\/b>/gi, "$1");
};
render() {
const {
document,
showCollection,
showPublished,
2019-04-09 04:47:27 +00:00
showPin,
feat: Memberships (#1032) * WIP * feat: Add collection.memberships endpoint * feat: Add ability to filter collection.memberships with query * WIP * Merge stashed work * feat: Add ability to filter memberships by permission * continued refactoring * paginated list component * Collection member management * fix: Incorrect policy data sent down after collection.update * Reduce duplication, add empty state * cleanup * fix: Modal close should be a real button * fix: Allow opening edit from modal * fix: remove unused methods * test: fix * Passing test suite * Refactor * fix: Flow UI errors * test: Add collections.update tests * lint * test: moar tests * fix: Missing scopes, more missing tests * fix: Handle collection privacy change over socket * fix: More membership scopes * fix: view endpoint permissions * fix: respond to privacy change on socket event * policy driven menus * fix: share endpoint policies * chore: Use policies to drive documents UI * alignment * fix: Header height * fix: Correct behavior when collection becomes private * fix: Header height for read-only collection * send id's over socket instead of serialized objects * fix: Remote policy change * fix: reduce collection fetching * More websocket efficiencies * fix: Document collection pinning * fix: Restored ability to edit drafts fix: Removed ability to star drafts * fix: Require write permissions to pin doc to collection * fix: Header title overlaying document actions at small screen sizes * fix: Jank on load caused by previous commit * fix: Double collection fetch post-publish * fix: Hide publish button if draft is in no longer accessible collection * fix: Always allow deleting drafts fix: Improved handling of deleted documents * feat: Show collections in drafts view feat: Show more obvious 'draft' badge on documents * fix: incorrect policies after publish to private collection * fix: Duplicating a draft publishes it
2019-10-06 01:42:03 +00:00
showDraft = true,
highlight,
context,
...rest
} = this.props;
const queryIsInTitle =
!!highlight &&
!!document.title.toLowerCase().includes(highlight.toLowerCase());
return (
2018-05-13 04:01:17 +00:00
<DocumentLink
to={{
pathname: document.url,
state: { title: document.title },
}}
2018-05-13 04:01:17 +00:00
{...rest}
>
<Heading>
<Title text={document.title || "Untitled"} highlight={highlight} />
{!document.isDraft &&
!document.isArchived && (
<Actions>
{document.isStarred ? (
<StyledStar onClick={this.unstar} solid />
) : (
<StyledStar onClick={this.star} />
)}
</Actions>
)}
feat: Memberships (#1032) * WIP * feat: Add collection.memberships endpoint * feat: Add ability to filter collection.memberships with query * WIP * Merge stashed work * feat: Add ability to filter memberships by permission * continued refactoring * paginated list component * Collection member management * fix: Incorrect policy data sent down after collection.update * Reduce duplication, add empty state * cleanup * fix: Modal close should be a real button * fix: Allow opening edit from modal * fix: remove unused methods * test: fix * Passing test suite * Refactor * fix: Flow UI errors * test: Add collections.update tests * lint * test: moar tests * fix: Missing scopes, more missing tests * fix: Handle collection privacy change over socket * fix: More membership scopes * fix: view endpoint permissions * fix: respond to privacy change on socket event * policy driven menus * fix: share endpoint policies * chore: Use policies to drive documents UI * alignment * fix: Header height * fix: Correct behavior when collection becomes private * fix: Header height for read-only collection * send id's over socket instead of serialized objects * fix: Remote policy change * fix: reduce collection fetching * More websocket efficiencies * fix: Document collection pinning * fix: Restored ability to edit drafts fix: Removed ability to star drafts * fix: Require write permissions to pin doc to collection * fix: Header title overlaying document actions at small screen sizes * fix: Jank on load caused by previous commit * fix: Double collection fetch post-publish * fix: Hide publish button if draft is in no longer accessible collection * fix: Always allow deleting drafts fix: Improved handling of deleted documents * feat: Show collections in drafts view feat: Show more obvious 'draft' badge on documents * fix: incorrect policies after publish to private collection * fix: Duplicating a draft publishes it
2019-10-06 01:42:03 +00:00
{document.isDraft &&
showDraft && (
<Tooltip
tooltip="Only visible to you"
delay={500}
placement="top"
>
<Badge>Draft</Badge>
</Tooltip>
)}
2019-04-09 04:47:27 +00:00
<StyledDocumentMenu document={document} showPin={showPin} />
</Heading>
{!queryIsInTitle && (
<ResultContext
text={context}
highlight={highlight ? SEARCH_RESULT_REGEX : undefined}
processResult={this.replaceResultMarks}
/>
)}
<PublishingInfo
document={document}
showCollection={showCollection}
showPublished={showPublished}
/>
</DocumentLink>
);
}
}
export default DocumentPreview;