chore: Upgrade Prettier 1.8 -> 2.0 (#1436)

This commit is contained in:
Tom Moor 2020-08-08 18:53:11 -07:00 committed by GitHub
parent 68dcb4de5f
commit e312b264a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
218 changed files with 1156 additions and 1169 deletions

View File

@ -12,7 +12,7 @@ export const Action = styled(Flex)`
flex-shrink: 0;
a {
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
height: 24px;
}
@ -26,7 +26,7 @@ export const Separator = styled.div`
margin-left: 12px;
width: 1px;
height: 28px;
background: ${props => props.theme.divider};
background: ${(props) => props.theme.divider};
`;
const Actions = styled(Flex)`
@ -35,8 +35,8 @@ const Actions = styled(Flex)`
right: 0;
left: 0;
border-radius: 3px;
background: ${props => props.theme.background};
transition: ${props => props.theme.backgroundTransition};
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
padding: 12px;
-webkit-backdrop-filter: blur(20px);

View File

@ -14,7 +14,7 @@ export default class Analytics extends React.Component<Props> {
// standard Google Analytics script
window.ga =
window.ga ||
function() {
function () {
// $FlowIssue
(ga.q = ga.q || []).push(arguments);
};

View File

@ -48,8 +48,8 @@ const IconWrapper = styled.div`
position: absolute;
bottom: -2px;
right: -2px;
background: ${props => props.theme.primary};
border: 2px solid ${props => props.theme.background};
background: ${(props) => props.theme.primary};
border: 2px solid ${(props) => props.theme.background};
border-radius: 100%;
width: 20px;
height: 20px;
@ -57,10 +57,10 @@ const IconWrapper = styled.div`
const CircleImg = styled.img`
display: block;
width: ${props => props.size}px;
height: ${props => props.size}px;
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
border-radius: 50%;
border: 2px solid ${props => props.theme.background};
border: 2px solid ${(props) => props.theme.background};
flex-shrink: 0;
`;

View File

@ -47,7 +47,9 @@ class AvatarWithPresence extends React.Component<Props> {
<strong>{user.name}</strong> {isCurrentUser && "(You)"}
<br />
{isPresent
? isEditing ? "currently editing" : "currently viewing"
? isEditing
? "currently editing"
: "currently viewing"
: `viewed ${distanceInWordsToNow(new Date(lastViewedAt))} ago`}
</Centered>
}
@ -77,7 +79,7 @@ const Centered = styled.div`
`;
const AvatarWrapper = styled.div`
opacity: ${props => (props.isPresent ? 1 : 0.5)};
opacity: ${(props) => (props.isPresent ? 1 : 0.5)};
transition: opacity 250ms ease-in-out;
`;

View File

@ -11,7 +11,8 @@ type Props = {
function Branding({ href = env.URL }: Props) {
return (
<Link href={href}>
<OutlineLogo size={16} />&nbsp;Outline
<OutlineLogo size={16} />
&nbsp;Outline
</Link>
);
}
@ -25,17 +26,17 @@ const Link = styled.a`
font-size: 14px;
text-decoration: none;
border-top-right-radius: 2px;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
display: flex;
align-items: center;
padding: 16px;
svg {
fill: ${props => props.theme.text};
fill: ${(props) => props.theme.text};
}
&:hover {
background: ${props => props.theme.sidebarBackground};
background: ${(props) => props.theme.sidebarBackground};
}
`;

View File

@ -40,7 +40,7 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
</React.Fragment>
)}
{collection.name}
{path.map(n => (
{path.map((n) => (
<React.Fragment key={n.id}>
<SmallSlash />
{n.title}
@ -61,7 +61,8 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
{isTemplate && (
<React.Fragment>
<CollectionName to="/templates">
<ShapesIcon color="currentColor" />&nbsp;
<ShapesIcon color="currentColor" />
&nbsp;
<span>Templates</span>
</CollectionName>
<Slash />
@ -70,14 +71,16 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
{isDraft && (
<React.Fragment>
<CollectionName to="/drafts">
<EditIcon color="currentColor" />&nbsp;
<EditIcon color="currentColor" />
&nbsp;
<span>Drafts</span>
</CollectionName>
<Slash />
</React.Fragment>
)}
<CollectionName to={collectionUrl(collection.id)}>
<CollectionIcon collection={collection} expanded />&nbsp;
<CollectionIcon collection={collection} expanded />
&nbsp;
<span>{collection.name}</span>
</CollectionName>
{isNestedDocument && (
@ -119,7 +122,7 @@ const SmallSlash = styled(GoToIcon)`
export const Slash = styled(GoToIcon)`
flex-shrink: 0;
fill: ${props => props.theme.divider};
fill: ${(props) => props.theme.divider};
`;
const Overflow = styled(MoreIcon)`
@ -134,7 +137,7 @@ const Overflow = styled(MoreIcon)`
`;
const Crumb = styled(Link)`
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
font-size: 15px;
height: 24px;
text-overflow: ellipsis;
@ -149,7 +152,7 @@ const Crumb = styled(Link)`
const CollectionName = styled(Link)`
display: flex;
flex-shrink: 0;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
font-size: 15px;
font-weight: 500;
white-space: nowrap;

View File

@ -14,7 +14,7 @@ export default class BreadcrumbMenu extends React.Component<Props> {
return (
<DropdownMenu label={this.props.label} position="center">
{path.map(item => (
{path.map((item) => (
<DropdownMenuItem as={Link} to={item.url} key={item.id}>
{item.title}
</DropdownMenuItem>

View File

@ -5,13 +5,13 @@ import { darken, lighten } from "polished";
import { ExpandedIcon } from "outline-icons";
const RealButton = styled.button`
display: ${props => (props.fullwidth ? "block" : "inline-block")};
width: ${props => (props.fullwidth ? "100%" : "auto")};
display: ${(props) => (props.fullwidth ? "block" : "inline-block")};
width: ${(props) => (props.fullwidth ? "100%" : "auto")};
margin: 0;
padding: 0;
border: 0;
background: ${props => props.theme.buttonBackground};
color: ${props => props.theme.buttonText};
background: ${(props) => props.theme.buttonBackground};
color: ${(props) => props.theme.buttonText};
box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
border-radius: 4px;
font-size: 14px;
@ -24,7 +24,7 @@ const RealButton = styled.button`
user-select: none;
svg {
fill: ${props => props.iconColor || props.theme.buttonText};
fill: ${(props) => props.iconColor || props.theme.buttonText};
}
&::-moz-focus-inner {
@ -33,12 +33,12 @@ const RealButton = styled.button`
}
&:hover {
background: ${props => darken(0.05, props.theme.buttonBackground)};
background: ${(props) => darken(0.05, props.theme.buttonBackground)};
}
&:focus {
transition-duration: 0.05s;
box-shadow: ${props => lighten(0.4, props.theme.buttonBackground)} 0px 0px
box-shadow: ${(props) => lighten(0.4, props.theme.buttonBackground)} 0px 0px
0px 3px;
outline: none;
}
@ -46,10 +46,10 @@ const RealButton = styled.button`
&:disabled {
cursor: default;
pointer-events: none;
color: ${props => props.theme.white50};
color: ${(props) => props.theme.white50};
}
${props =>
${(props) =>
props.neutral &&
`
background: ${props.theme.buttonNeutralBackground};
@ -80,9 +80,9 @@ const RealButton = styled.button`
&:disabled {
color: ${props.theme.textTertiary};
}
`} ${props =>
props.danger &&
`
`} ${(props) =>
props.danger &&
`
background: ${props.theme.danger};
color: ${props.theme.white};
@ -103,20 +103,20 @@ const Label = styled.span`
white-space: nowrap;
text-overflow: ellipsis;
${props => props.hasIcon && "padding-left: 4px;"};
${(props) => props.hasIcon && "padding-left: 4px;"};
`;
export const Inner = styled.span`
display: flex;
padding: 0 8px;
padding-right: ${props => (props.disclosure ? 2 : 8)}px;
line-height: ${props => (props.hasIcon ? 24 : 32)}px;
padding-right: ${(props) => (props.disclosure ? 2 : 8)}px;
line-height: ${(props) => (props.hasIcon ? 24 : 32)}px;
justify-content: center;
align-items: center;
min-height: 30px;
${props => props.hasIcon && props.hasText && "padding-left: 4px;"};
${props => props.hasIcon && !props.hasText && "padding: 0 4px;"};
${(props) => props.hasIcon && props.hasText && "padding-left: 4px;"};
${(props) => props.hasIcon && !props.hasText && "padding: 0 4px;"};
`;
export type Props = {

View File

@ -15,13 +15,13 @@ export type Props = {
const LabelText = styled.span`
font-weight: 500;
margin-left: ${props => (props.small ? "6px" : "10px")};
${props => (props.small ? `color: ${props.theme.textSecondary}` : "")};
margin-left: ${(props) => (props.small ? "6px" : "10px")};
${(props) => (props.small ? `color: ${props.theme.textSecondary}` : "")};
`;
const Wrapper = styled.div`
padding-bottom: 8px;
${props => (props.small ? "font-size: 14px" : "")};
${(props) => (props.small ? "font-size: 14px" : "")};
`;
const Label = styled.label`

View File

@ -32,27 +32,27 @@ class Collaborators extends React.Component<Props> {
const documentViews = views.inDocument(document.id);
const presentIds = documentPresence.map(p => p.userId);
const presentIds = documentPresence.map((p) => p.userId);
const editingIds = documentPresence
.filter(p => p.isEditing)
.map(p => p.userId);
.filter((p) => p.isEditing)
.map((p) => p.userId);
// ensure currently present via websocket are always ordered first
const mostRecentViewers = sortBy(
documentViews.slice(0, MAX_AVATAR_DISPLAY),
view => {
(view) => {
return presentIds.includes(view.user.id);
}
);
const viewersKeyedByUserId = keyBy(mostRecentViewers, v => v.user.id);
const viewersKeyedByUserId = keyBy(mostRecentViewers, (v) => v.user.id);
const overflow = documentViews.length - mostRecentViewers.length;
return (
<Facepile
users={mostRecentViewers.map(v => v.user)}
users={mostRecentViewers.map((v) => v.user)}
overflow={overflow}
renderAvatar={user => {
renderAvatar={(user) => {
const isPresent = presentIds.includes(user.id);
const isEditing = editingIds.includes(user.id);
const { lastViewedAt } = viewersKeyedByUserId[user.id];

View File

@ -133,16 +133,16 @@ const Wrapper = styled(Flex)`
top: 0;
right: 0;
z-index: 1;
min-width: ${props => props.theme.sidebarWidth};
min-width: ${(props) => props.theme.sidebarWidth};
height: 100%;
overflow-y: auto;
overscroll-behavior: none;
`;
const Sidebar = styled(Flex)`
background: ${props => props.theme.background};
min-width: ${props => props.theme.sidebarWidth};
border-left: 1px solid ${props => props.theme.divider};
background: ${(props) => props.theme.background};
min-width: ${(props) => props.theme.sidebarWidth};
border-left: 1px solid ${(props) => props.theme.divider};
z-index: 1;
`;

View File

@ -66,7 +66,7 @@ const StyledRevisionMenu = styled(RevisionMenu)`
`;
const StyledNavLink = styled(NavLink)`
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
display: block;
padding: 8px 16px;
font-size: 15px;

View File

@ -17,7 +17,7 @@ export default function DocumentList({ limit, documents, ...rest }: Props) {
mode={ArrowKeyNavigation.mode.VERTICAL}
defaultActiveChildIndex={0}
>
{items.map(document => (
{items.map((document) => (
<DocumentPreview key={document.id} document={document} {...rest} />
))}
</ArrowKeyNavigation>

View File

@ -48,7 +48,7 @@ class DocumentPreview extends React.Component<Props> {
return tag.replace(/<b\b[^>]*>(.*?)<\/b>/gi, "$1");
};
handleNewFromTemplate = event => {
handleNewFromTemplate = (event) => {
event.preventDefault();
event.stopPropagation();
@ -97,18 +97,14 @@ class DocumentPreview extends React.Component<Props> {
)}
</Actions>
)}
{document.isDraft &&
showDraft && (
<Tooltip
tooltip="Only visible to you"
delay={500}
placement="top"
>
<Badge>Draft</Badge>
</Tooltip>
)}
{document.isTemplate &&
showTemplate && <Badge primary>Template</Badge>}
{document.isDraft && showDraft && (
<Tooltip tooltip="Only visible to you" delay={500} placement="top">
<Badge>Draft</Badge>
</Tooltip>
)}
{document.isTemplate && showTemplate && (
<Badge primary>Template</Badge>
)}
<SecondaryActions>
{document.isTemplate &&
!document.isArchived &&
@ -120,7 +116,8 @@ class DocumentPreview extends React.Component<Props> {
>
New doc
</Button>
)}&nbsp;
)}
&nbsp;
<DocumentMenu document={document} showPin={showPin} />
</SecondaryActions>
</Heading>
@ -146,7 +143,7 @@ const StyledStar = withTheme(styled(({ solid, theme, ...props }) => (
<StarredIcon color={theme.text} {...props} />
))`
flex-shrink: 0;
opacity: ${props => (props.solid ? "1 !important" : 0)};
opacity: ${(props) => (props.solid ? "1 !important" : 0)};
transition: all 100ms ease-in-out;
&:hover {
@ -182,7 +179,7 @@ const DocumentLink = styled(Link)`
&:hover,
&:active,
&:focus {
background: ${props => props.theme.listItemHoverBackground};
background: ${(props) => props.theme.listItemHoverBackground};
outline: none;
${SecondaryActions} {
@ -207,7 +204,7 @@ const Heading = styled.h3`
margin-bottom: 0.25em;
overflow: hidden;
white-space: nowrap;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
`;
@ -225,7 +222,7 @@ const Title = styled(Highlight)`
const ResultContext = styled(Highlight)`
display: block;
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
font-size: 14px;
margin-top: -0.25em;
margin-bottom: 0.25em;

View File

@ -30,12 +30,12 @@ type Props = {
export const GlobalStyles = createGlobalStyle`
.activeDropZone {
border-radius: 4px;
background: ${props => props.theme.slateDark};
svg { fill: ${props => props.theme.white}; }
background: ${(props) => props.theme.slateDark};
svg { fill: ${(props) => props.theme.white}; }
}
.activeDropZone a {
color: ${props => props.theme.white} !important;
color: ${(props) => props.theme.white} !important;
}
`;

View File

@ -204,7 +204,7 @@ class DropdownMenu extends React.Component<Props> {
onClick={
typeof children === "function"
? undefined
: ev => {
: (ev) => {
ev.stopPropagation();
closePortal();
}
@ -245,24 +245,24 @@ const Position = styled.div`
${({ bottom }) => (bottom !== undefined ? `bottom: ${bottom}px` : "")};
max-height: 75%;
z-index: 1000;
transform: ${props =>
transform: ${(props) =>
props.position === "center" ? "translateX(-50%)" : "initial"};
pointer-events: none;
`;
const Menu = styled.div`
animation: ${fadeAndScaleIn} 200ms ease;
transform-origin: ${props => (props.left !== undefined ? "25%" : "75%")} 0;
transform-origin: ${(props) => (props.left !== undefined ? "25%" : "75%")} 0;
backdrop-filter: blur(10px);
background: ${props => rgba(props.theme.menuBackground, 0.8)};
border: ${props =>
background: ${(props) => rgba(props.theme.menuBackground, 0.8)};
border: ${(props) =>
props.theme.menuBorder ? `1px solid ${props.theme.menuBorder}` : "none"};
border-radius: 2px;
padding: 0.5em 0;
min-width: 180px;
overflow: hidden;
overflow-y: auto;
box-shadow: ${props => props.theme.menuShadow};
box-shadow: ${(props) => props.theme.menuShadow};
pointer-events: all;
hr {
@ -278,7 +278,7 @@ export const Header = styled.h3`
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: ${props => props.theme.sidebarText};
color: ${(props) => props.theme.sidebarText};
letter-spacing: 0.04em;
margin: 1em 12px 0.5em;
`;

View File

@ -29,7 +29,8 @@ const DropdownMenuItem = ({
<React.Fragment>
<CheckmarkIcon
color={selected === false ? "transparent" : undefined}
/>&nbsp;
/>
&nbsp;
</React.Fragment>
)}
{children}
@ -44,7 +45,7 @@ const MenuItem = styled.a`
width: 100%;
min-height: 32px;
color: ${props =>
color: ${(props) =>
props.disabled ? props.theme.textTertiary : props.theme.textSecondary};
justify-content: left;
align-items: center;
@ -57,10 +58,10 @@ const MenuItem = styled.a`
}
svg {
opacity: ${props => (props.disabled ? ".5" : 1)};
opacity: ${(props) => (props.disabled ? ".5" : 1)};
}
${props =>
${(props) =>
props.disabled
? "pointer-events: none;"
: `

View File

@ -81,11 +81,11 @@ class Editor extends React.Component<Props> {
}
const StyledEditor = styled(RichMarkdownEditor)`
flex-grow: ${props => (props.grow ? 1 : 0)};
flex-grow: ${(props) => (props.grow ? 1 : 0)};
justify-content: start;
> div {
transition: ${props => props.theme.backgroundTransition};
transition: ${(props) => props.theme.backgroundTransition};
}
.notice-block.tip,
@ -95,13 +95,13 @@ const StyledEditor = styled(RichMarkdownEditor)`
p {
a {
color: ${props => props.theme.text};
border-bottom: 1px solid ${props => lighten(0.5, props.theme.text)};
color: ${(props) => props.theme.text};
border-bottom: 1px solid ${(props) => lighten(0.5, props.theme.text)};
text-decoration: none !important;
font-weight: 500;
&:hover {
border-bottom: 1px solid ${props => props.theme.text};
border-bottom: 1px solid ${(props) => props.theme.text};
text-decoration: none;
}
}

View File

@ -2,7 +2,7 @@
import styled from "styled-components";
const Empty = styled.p`
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
`;
export default Empty;

View File

@ -48,9 +48,9 @@ class ErrorBoundary extends React.Component<Props> {
<PageTitle title="Something Unexpected Happened" />
<h1>Something Unexpected Happened</h1>
<HelpText>
Sorry, an unrecoverable error occurred{isReported &&
" our engineers have been notified"}. Please try reloading the
page, it may have been a temporary glitch.
Sorry, an unrecoverable error occurred
{isReported && " our engineers have been notified"}. Please try
reloading the page, it may have been a temporary glitch.
</HelpText>
{this.showDetails && <Pre>{this.error.toString()}</Pre>}
<p>
@ -73,7 +73,7 @@ class ErrorBoundary extends React.Component<Props> {
}
const Pre = styled.pre`
background: ${props => props.theme.smoke};
background: ${(props) => props.theme.smoke};
padding: 16px;
border-radius: 4px;
font-size: 12px;

View File

@ -31,7 +31,7 @@ class Facepile extends React.Component<Props> {
<span>+{overflow}</span>
</More>
)}
{users.map(user => (
{users.map((user) => (
<AvatarWrapper key={user.id}>{renderAvatar(user)}</AvatarWrapper>
))}
</Avatars>
@ -56,12 +56,12 @@ const More = styled.div`
flex-direction: column;
align-items: center;
justify-content: center;
min-width: ${props => props.size}px;
height: ${props => props.size}px;
min-width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
border-radius: 100%;
background: ${props => props.theme.slate};
color: ${props => props.theme.text};
border: 2px solid ${props => props.theme.background};
background: ${(props) => props.theme.slate};
color: ${(props) => props.theme.text};
border: 2px solid ${(props) => props.theme.background};
text-align: center;
font-size: 11px;
font-weight: 600;

View File

@ -3,7 +3,7 @@ import styled from "styled-components";
import { fadeIn } from "shared/styles/animations";
const Fade = styled.span`
animation: ${fadeIn} ${props => props.timing || "250ms"} ease-in-out;
animation: ${fadeIn} ${(props) => props.timing || "250ms"} ease-in-out;
`;
export default Fade;

View File

@ -41,7 +41,7 @@ class GroupListItem extends React.Component<Props> {
const membershipsInGroup = groupMemberships.inGroup(group.id);
const users = membershipsInGroup
.slice(0, MAX_AVATAR_DISPLAY)
.map(gm => gm.user);
.map((gm) => gm.user);
const overflow = memberCount - users.length;

View File

@ -3,8 +3,8 @@ import styled from "styled-components";
const HelpText = styled.p`
margin-top: 0;
color: ${props => props.theme.textSecondary};
font-size: ${props => (props.small ? "13px" : "inherit")};
color: ${(props) => props.theme.textSecondary};
font-size: ${(props) => (props.small ? "13px" : "inherit")};
`;
export default HelpText;

View File

@ -38,7 +38,7 @@ function Highlight({
}
const Mark = styled.mark`
background: ${props => props.theme.yellow};
background: ${(props) => props.theme.yellow};
border-radius: 2px;
padding: 0 4px;
`;

View File

@ -57,42 +57,39 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
}
};
React.useEffect(
() => {
if (slug) {
documents.prefetchDocument(slug, {
prefetch: true,
});
}
React.useEffect(() => {
if (slug) {
documents.prefetchDocument(slug, {
prefetch: true,
});
}
startOpenTimer();
startOpenTimer();
if (cardRef.current) {
cardRef.current.addEventListener("mouseenter", stopCloseTimer);
cardRef.current.addEventListener("mouseleave", startCloseTimer);
}
node.addEventListener("mouseout", startCloseTimer);
node.addEventListener("mouseover", stopCloseTimer);
node.addEventListener("mouseover", startOpenTimer);
return () => {
node.removeEventListener("mouseout", startCloseTimer);
node.removeEventListener("mouseover", stopCloseTimer);
node.removeEventListener("mouseover", startOpenTimer);
if (cardRef.current) {
cardRef.current.addEventListener("mouseenter", stopCloseTimer);
cardRef.current.addEventListener("mouseleave", startCloseTimer);
cardRef.current.removeEventListener("mouseenter", stopCloseTimer);
cardRef.current.removeEventListener("mouseleave", startCloseTimer);
}
node.addEventListener("mouseout", startCloseTimer);
node.addEventListener("mouseover", stopCloseTimer);
node.addEventListener("mouseover", startOpenTimer);
return () => {
node.removeEventListener("mouseout", startCloseTimer);
node.removeEventListener("mouseover", stopCloseTimer);
node.removeEventListener("mouseover", startOpenTimer);
if (cardRef.current) {
cardRef.current.removeEventListener("mouseenter", stopCloseTimer);
cardRef.current.removeEventListener("mouseleave", startCloseTimer);
}
if (timerClose.current) {
clearTimeout(timerClose.current);
}
};
},
[node]
);
if (timerClose.current) {
clearTimeout(timerClose.current);
}
};
}, [node]);
const anchorBounds = node.getBoundingClientRect();
const cardBounds = cardRef.current
@ -112,7 +109,7 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
>
<div ref={cardRef}>
<HoverPreviewDocument url={node.href}>
{content =>
{(content) =>
isVisible ? (
<Animate>
<Card>
@ -156,8 +153,8 @@ const CardContent = styled.div`
// &:after — gradient mask for overflow text
const Card = styled.div`
backdrop-filter: blur(10px);
background: ${props => props.theme.background};
border: ${props =>
background: ${(props) => props.theme.background};
border: ${(props) =>
props.theme.menuBorder ? `1px solid ${props.theme.menuBorder}` : "none"};
border-radius: 4px;
box-shadow: 0 30px 90px -20px rgba(0, 0, 0, 0.3),
@ -179,15 +176,15 @@ const Card = styled.div`
pointer-events: none;
background: linear-gradient(
90deg,
${props => transparentize(1, props.theme.background)} 0%,
${props => transparentize(1, props.theme.background)} 75%,
${props => props.theme.background} 90%
${(props) => transparentize(1, props.theme.background)} 0%,
${(props) => transparentize(1, props.theme.background)} 75%,
${(props) => props.theme.background} 90%
);
bottom: 0;
left: 0;
right: 0;
height: 1.7em;
border-bottom: 16px solid ${props => props.theme.background};
border-bottom: 16px solid ${(props) => props.theme.background};
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
@ -205,7 +202,7 @@ const Position = styled.div`
const Pointer = styled.div`
top: -22px;
left: ${props => props.offset}px;
left: ${(props) => props.offset}px;
width: 22px;
height: 22px;
position: absolute;
@ -222,14 +219,14 @@ const Pointer = styled.div`
&:before {
border: 8px solid transparent;
border-bottom-color: ${props =>
border-bottom-color: ${(props) =>
props.theme.menuBorder || "rgba(0, 0, 0, 0.1)"};
right: -1px;
}
&:after {
border: 7px solid transparent;
border-bottom-color: ${props => props.theme.background};
border-bottom-color: ${(props) => props.theme.background};
}
`;

View File

@ -11,7 +11,7 @@ import DocumentMeta from "components/DocumentMeta";
type Props = {
url: string,
documents: DocumentsStore,
children: React.Node => React.Node,
children: (React.Node) => React.Node,
};
function HoverPreviewDocument({ url, documents, children }: Props) {
@ -45,7 +45,7 @@ const Content = styled(Link)`
const Heading = styled.h2`
margin: 0 0 0.75em;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
`;
export default inject("documents")(observer(HoverPreviewDocument));

View File

@ -166,7 +166,7 @@ class IconPicker extends React.Component<Props> {
const Component = icons[this.props.icon || "collection"].component;
return (
<Wrapper ref={ref => (this.node = ref)}>
<Wrapper ref={(ref) => (this.node = ref)}>
<label>
<LabelText>Icon</LabelText>
</label>
@ -179,7 +179,7 @@ class IconPicker extends React.Component<Props> {
}
>
<Icons onClick={preventEventBubble}>
{Object.keys(icons).map(name => {
{Object.keys(icons).map((name) => {
const Component = icons[name].component;
return (
<IconButton
@ -195,7 +195,7 @@ class IconPicker extends React.Component<Props> {
<Flex onClick={preventEventBubble}>
<ColorPicker
color={this.props.color}
onChange={color =>
onChange={(color) =>
this.props.onChange(color.hex, this.props.icon)
}
colors={colors}
@ -214,7 +214,7 @@ const Icons = styled.div`
`;
const LabelButton = styled(NudeButton)`
border: 1px solid ${props => props.theme.inputBorder};
border: 1px solid ${(props) => props.theme.inputBorder};
width: 32px;
height: 32px;
`;

View File

@ -9,29 +9,29 @@ import Flex from "components/Flex";
const RealTextarea = styled.textarea`
border: 0;
flex: 1;
padding: 8px 12px 8px ${props => (props.hasIcon ? "8px" : "12px")};
padding: 8px 12px 8px ${(props) => (props.hasIcon ? "8px" : "12px")};
outline: none;
background: none;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
&:disabled,
&::placeholder {
color: ${props => props.theme.placeholder};
color: ${(props) => props.theme.placeholder};
}
`;
const RealInput = styled.input`
border: 0;
flex: 1;
padding: 8px 12px 8px ${props => (props.hasIcon ? "8px" : "12px")};
padding: 8px 12px 8px ${(props) => (props.hasIcon ? "8px" : "12px")};
outline: none;
background: none;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
height: 30px;
&:disabled,
&::placeholder {
color: ${props => props.theme.placeholder};
color: ${(props) => props.theme.placeholder};
}
&::-webkit-search-cancel-button {
@ -40,8 +40,8 @@ const RealInput = styled.input`
`;
const Wrapper = styled.div`
flex: ${props => (props.flex ? "1" : "0")};
max-width: ${props => (props.short ? "350px" : "100%")};
flex: ${(props) => (props.flex ? "1" : "0")};
max-width: ${(props) => (props.short ? "350px" : "100%")};
min-height: ${({ minHeight }) => (minHeight ? `${minHeight}px` : "0")};
max-height: ${({ maxHeight }) => (maxHeight ? `${maxHeight}px` : "initial")};
`;
@ -56,16 +56,17 @@ const IconWrapper = styled.span`
export const Outline = styled(Flex)`
display: flex;
flex: 1;
margin: ${props => (props.margin !== undefined ? props.margin : "0 0 16px")};
margin: ${(props) =>
props.margin !== undefined ? props.margin : "0 0 16px"};
color: inherit;
border-width: 1px;
border-style: solid;
border-color: ${props =>
border-color: ${(props) =>
props.hasError
? "red"
: props.focused
? props.theme.inputBorderFocused
: props.theme.inputBorder};
? props.theme.inputBorderFocused
: props.theme.inputBorder};
border-radius: 4px;
font-weight: normal;
align-items: center;
@ -147,7 +148,7 @@ class Input extends React.Component<Props> {
<Outline focused={this.focused} margin={margin}>
{icon && <IconWrapper>{icon}</IconWrapper>}
<InputComponent
ref={ref => (this.input = ref)}
ref={(ref) => (this.input = ref)}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
type={type === "textarea" ? undefined : type}

View File

@ -30,7 +30,7 @@ class InputSearch extends React.Component<Props> {
}
}
handleSearchInput = ev => {
handleSearchInput = (ev) => {
ev.preventDefault();
this.props.history.push(
searchUrl(ev.target.value, this.props.collectionId)
@ -50,7 +50,7 @@ class InputSearch extends React.Component<Props> {
return (
<InputMaxWidth
ref={ref => (this.input = ref)}
ref={(ref) => (this.input = ref)}
type="search"
placeholder={placeholder}
onInput={this.handleSearchInput}

View File

@ -12,11 +12,11 @@ const Select = styled.select`
padding: 8px 12px;
outline: none;
background: none;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
&:disabled,
&::placeholder {
color: ${props => props.theme.placeholder};
color: ${(props) => props.theme.placeholder};
}
`;
@ -57,7 +57,7 @@ class InputSelect extends React.Component<Props> {
))}
<Outline focused={this.focused} className={className}>
<Select onBlur={this.handleBlur} onFocus={this.handleFocus} {...rest}>
{options.map(option => (
{options.map((option) => (
<option value={option.value} key={option.value}>
{option.label}
</option>

View File

@ -7,13 +7,13 @@ const Key = styled.kbd`
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier,
monospace;
line-height: 10px;
color: ${props => props.theme.almostBlack};
color: ${(props) => props.theme.almostBlack};
vertical-align: middle;
background-color: ${props => props.theme.smokeLight};
border: solid 1px ${props => props.theme.slateLight};
border-bottom-color: ${props => props.theme.slate};
background-color: ${(props) => props.theme.smokeLight};
border: solid 1px ${(props) => props.theme.slateLight};
border-bottom-color: ${(props) => props.theme.slate};
border-radius: 3px;
box-shadow: inset 0 -1px 0 ${props => props.theme.slate};
box-shadow: inset 0 -1px 0 ${(props) => props.theme.slate};
`;
export default Key;

View File

@ -21,7 +21,7 @@ export const Label = styled(Flex)`
font-size: 13px;
font-weight: 500;
text-transform: uppercase;
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
letter-spacing: 0.04em;
`;

View File

@ -142,8 +142,8 @@ class Layout extends React.Component<Props> {
}
const Container = styled(Flex)`
background: ${props => props.theme.background};
transition: ${props => props.theme.backgroundTransition};
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
position: relative;
width: 100%;
min-height: 100%;
@ -158,7 +158,7 @@ const Content = styled(Flex)`
}
${breakpoint("tablet")`
margin-left: ${props => (props.editMode ? 0 : props.theme.sidebarWidth)};
margin-left: ${(props) => (props.editMode ? 0 : props.theme.sidebarWidth)};
`};
`;

View File

@ -27,9 +27,9 @@ const ListItem = ({ image, title, subtitle, actions }: Props) => {
const Wrapper = styled.li`
display: flex;
padding: ${props => (props.compact ? "8px" : "12px")} 0;
padding: ${(props) => (props.compact ? "8px" : "12px")} 0;
margin: 0;
border-bottom: 1px solid ${props => props.theme.divider};
border-bottom: 1px solid ${(props) => props.theme.divider};
&:last-child {
border-bottom: 0;
@ -59,7 +59,7 @@ const Content = styled(Flex)`
const Subtitle = styled.p`
margin: 0;
font-size: 14px;
color: ${props => props.theme.slate};
color: ${(props) => props.theme.slate};
`;
const Actions = styled.div`

View File

@ -13,7 +13,7 @@ type Props = {
const Placeholder = ({ count }: Props) => {
return (
<Fade>
{times(count || 2, index => (
{times(count || 2, (index) => (
<Item key={index} column auto>
<Mask />
</Item>

View File

@ -13,7 +13,7 @@ type Props = {
const ListPlaceHolder = ({ count }: Props) => {
return (
<Fade>
{times(count || 2, index => (
{times(count || 2, (index) => (
<Item key={index} column auto>
<Mask header />
<Mask />

View File

@ -27,10 +27,11 @@ class Mask extends React.Component<Props> {
}
const Redacted = styled(Flex)`
width: ${props => (props.header ? props.width / 2 : props.width)}%;
height: ${props => (props.height ? props.height : props.header ? 24 : 18)}px;
width: ${(props) => (props.header ? props.width / 2 : props.width)}%;
height: ${(props) =>
props.height ? props.height : props.header ? 24 : 18}px;
margin-bottom: 6px;
background-color: ${props => props.theme.divider};
background-color: ${(props) => props.theme.divider};
animation: ${pulsate} 1.3s infinite;
&:last-child {

View File

@ -21,7 +21,7 @@ type Props = {
const GlobalStyles = createGlobalStyle`
.ReactModal__Overlay {
background-color: ${props =>
background-color: ${(props) =>
transparentize(0.25, props.theme.background)} !important;
z-index: 100;
}
@ -30,7 +30,7 @@ const GlobalStyles = createGlobalStyle`
.ReactModalPortal + .ReactModalPortal {
.ReactModal__Overlay {
margin-left: 12px;
box-shadow: 0 -2px 10px ${props => props.theme.shadow};
box-shadow: 0 -2px 10px ${(props) => props.theme.shadow};
border-radius: 8px 0 0 8px;
overflow: hidden;
}
@ -72,7 +72,7 @@ const Modal = ({
isOpen={isOpen}
{...rest}
>
<Content onClick={ev => ev.stopPropagation()} column>
<Content onClick={(ev) => ev.stopPropagation()} column>
{title && <h1>{title}</h1>}
{children}
@ -109,8 +109,8 @@ const StyledModal = styled(ReactModal)`
align-items: flex-start;
overflow-x: hidden;
overflow-y: auto;
background: ${props => props.theme.background};
transition: ${props => props.theme.backgroundTransition};
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
padding: 8vh 2rem 2rem;
outline: none;
@ -133,7 +133,7 @@ const Close = styled(NudeButton)`
right: 0;
margin: 12px;
opacity: 0.75;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
width: auto;
height: auto;
@ -153,7 +153,7 @@ const Back = styled(NudeButton)`
top: 2rem;
left: 2rem;
opacity: 0.75;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
width: auto;
height: auto;

View File

@ -2,8 +2,8 @@
import styled from "styled-components";
const Notice = styled.p`
background: ${props => props.theme.sidebarBackground};
color: ${props => props.theme.sidebarText};
background: ${(props) => props.theme.sidebarBackground};
color: ${(props) => props.theme.sidebarText};
padding: 10px 12px;
border-radius: 4px;
position: relative;

View File

@ -14,7 +14,7 @@ const Button = styled.button`
&:focus {
transition-duration: 0.05s;
box-shadow: ${props => lighten(0.4, props.theme.buttonBackground)} 0px 0px
box-shadow: ${(props) => lighten(0.4, props.theme.buttonBackground)} 0px 0px
0px 3px;
outline: none;
}

View File

@ -25,7 +25,7 @@ class PaginatedDocumentList extends React.Component<Props> {
heading={heading}
fetch={fetch}
options={options}
renderItem={item => (
renderItem={(item) => (
<DocumentPreview key={item.id} document={item} {...rest} />
)}
/>

View File

@ -14,7 +14,7 @@ type Props = {
heading?: React.Node,
empty?: React.Node,
items: any[],
renderItem: any => React.Node,
renderItem: (any) => React.Node,
};
@observer

View File

@ -44,7 +44,7 @@ class PathToDocument extends React.Component<Props> {
<Component ref={ref} onClick={this.handleClick} href="" selectable>
{collection && <CollectionIcon collection={collection} />}
{result.path
.map(doc => <Title key={doc.id}>{doc.title}</Title>)
.map((doc) => <Title key={doc.id}>{doc.title}</Title>)
.reduce((prev, curr) => [prev, <StyledGoToIcon />, curr])}
{document && (
<Flex>
@ -73,7 +73,7 @@ const ResultWrapper = styled.div`
margin-left: -4px;
user-select: none;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
cursor: default;
`;
@ -85,7 +85,7 @@ const ResultWrapperLink = styled(ResultWrapper.withComponent("a"))`
&:hover,
&:active,
&:focus {
background: ${props => props.theme.listItemHoverBackground};
background: ${(props) => props.theme.listItemHoverBackground};
outline: none;
}
`;

View File

@ -10,16 +10,16 @@ import CollectionsStore from "stores/CollectionsStore";
import AuthStore from "stores/AuthStore";
const Container = styled(Flex)`
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
font-size: 13px;
white-space: nowrap;
overflow: hidden;
`;
const Modified = styled.span`
color: ${props =>
color: ${(props) =>
props.highlight ? props.theme.text : props.theme.textTertiary};
font-weight: ${props => (props.highlight ? "600" : "400")};
font-weight: ${(props) => (props.highlight ? "600" : "400")};
`;
type Props = {
@ -104,15 +104,14 @@ function PublishingInfo({
<Container align="center" {...rest}>
{updatedByMe ? "You" : updatedBy.name}&nbsp;
{content}
{showCollection &&
collection && (
<span>
&nbsp;in&nbsp;
<strong>
<Breadcrumb document={document} onlyText />
</strong>
</span>
)}
{showCollection && collection && (
<span>
&nbsp;in&nbsp;
<strong>
<Breadcrumb document={document} onlyText />
</strong>
</span>
)}
{children}
</Container>
);

View File

@ -31,7 +31,7 @@ const Wrapper = styled.div`
overflow-x: hidden;
overscroll-behavior: none;
-webkit-overflow-scrolling: touch;
box-shadow: ${props =>
box-shadow: ${(props) =>
props.shadow ? "0 1px inset rgba(0,0,0,.1)" : "none"};
transition: all 250ms ease-in-out;
`;

View File

@ -119,7 +119,8 @@ class MainSidebar extends React.Component<Props> {
icon={<EditIcon color="currentColor" />}
label={
<Drafts align="center">
Drafts{draftDocumentsCount > 0 && (
Drafts
{draftDocumentsCount > 0 && (
<Bubble count={draftDocumentsCount} />
)}
</Drafts>

View File

@ -146,13 +146,12 @@ class SettingsSidebar extends React.Component<Props> {
/>
</Section>
)}
{can.update &&
env.DEPLOYMENT !== "hosted" && (
<Section>
<Header>Installation</Header>
<Version />
</Section>
)}
{can.update && env.DEPLOYMENT !== "hosted" && (
<Section>
<Header>Installation</Header>
<Version />
</Section>
)}
</Scrollable>
</Flex>
</Sidebar>

View File

@ -67,9 +67,10 @@ const Container = styled(Flex)`
top: 0;
bottom: 0;
width: 100%;
background: ${props => props.theme.sidebarBackground};
transition: left 100ms ease-out, ${props => props.theme.backgroundTransition};
margin-left: ${props => (props.mobileSidebarVisible ? 0 : "-100%")};
background: ${(props) => props.theme.sidebarBackground};
transition: left 100ms ease-out,
${(props) => props.theme.backgroundTransition};
margin-left: ${(props) => (props.mobileSidebarVisible ? 0 : "-100%")};
z-index: 1000;
@media print {
@ -80,7 +81,7 @@ const Container = styled(Flex)`
&:before,
&:after {
content: "";
background: ${props => props.theme.sidebarBackground};
background: ${(props) => props.theme.sidebarBackground};
position: absolute;
top: -50vh;
left: 0;
@ -94,8 +95,8 @@ const Container = styled(Flex)`
}
${breakpoint("tablet")`
left: ${props => (props.editMode ? `-${props.theme.sidebarWidth}` : 0)};
width: ${props => props.theme.sidebarWidth};
left: ${(props) => (props.editMode ? `-${props.theme.sidebarWidth}` : 0)};
width: ${(props) => props.theme.sidebarWidth};
margin: 0;
z-index: 3;
`};
@ -106,8 +107,8 @@ const Toggle = styled.a`
align-items: center;
position: fixed;
top: 0;
left: ${props => (props.mobileSidebarVisible ? "auto" : 0)};
right: ${props => (props.mobileSidebarVisible ? 0 : "auto")};
left: ${(props) => (props.mobileSidebarVisible ? "auto" : 0)};
right: ${(props) => (props.mobileSidebarVisible ? 0 : "auto")};
z-index: 1;
margin: 12px;

View File

@ -14,8 +14,8 @@ const Bubble = ({ count }: Props) => {
const Count = styled.div`
animation: ${bounceIn} 600ms;
transform-origin: center center;
color: ${props => props.theme.white};
background: ${props => props.theme.slateDark};
color: ${(props) => props.theme.white};
background: ${(props) => props.theme.slateDark};
display: inline-block;
font-feature-settings: "tnum";
font-weight: 600;

View File

@ -61,7 +61,7 @@ class CollectionLink extends React.Component<Props> {
}
>
<Flex column>
{collection.documents.map(node => (
{collection.documents.map((node) => (
<DocumentLink
key={node.id}
node={node}

View File

@ -57,7 +57,7 @@ class Collections extends React.Component<Props> {
const content = (
<React.Fragment>
{collections.orderedData.map(collection => (
{collections.orderedData.map((collection) => (
<CollectionLink
key={collection.id}
documents={documents}
@ -94,6 +94,9 @@ class Collections extends React.Component<Props> {
}
}
export default inject("collections", "ui", "documents", "policies")(
withRouter(Collections)
);
export default inject(
"collections",
"ui",
"documents",
"policies"
)(withRouter(Collections));

View File

@ -76,7 +76,7 @@ class DocumentLink extends React.Component<Props> {
collection &&
(collection
.pathToDocument(activeDocument)
.map(entry => entry.id)
.map((entry) => entry.id)
.includes(node.id) ||
this.isActiveDocument())
);
@ -110,14 +110,12 @@ class DocumentLink extends React.Component<Props> {
onClose={() => (this.menuOpen = false)}
/>
</Fade>
) : (
undefined
)
) : undefined
}
>
{this.hasChildDocuments() && (
<DocumentChildren column>
{node.children.map(childNode => (
{node.children.map((childNode) => (
<DocumentLink
key={childNode.id}
collection={collection}

View File

@ -6,7 +6,7 @@ const Header = styled(Flex)`
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: ${props => props.theme.sidebarText};
color: ${(props) => props.theme.sidebarText};
letter-spacing: 0.04em;
margin: 4px 16px;
`;

View File

@ -46,7 +46,7 @@ const Subheading = styled.div`
font-size: 11px;
text-transform: uppercase;
font-weight: 500;
color: ${props => props.theme.sidebarText};
color: ${(props) => props.theme.sidebarText};
`;
const TeamName = styled.div`
@ -54,7 +54,7 @@ const TeamName = styled.div`
padding-left: 10px;
padding-right: 24px;
font-weight: 600;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
text-decoration: none;
font-size: 16px;
`;

View File

@ -108,11 +108,11 @@ const IconWrapper = styled.span`
`;
const Action = styled.span`
display: ${props => (props.menuOpen ? "inline" : "none")};
display: ${(props) => (props.menuOpen ? "inline" : "none")};
position: absolute;
top: 4px;
right: 4px;
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
svg {
opacity: 0.75;
@ -132,17 +132,17 @@ const StyledNavLink = styled(NavLink)`
text-overflow: ellipsis;
padding: 4px 16px;
border-radius: 4px;
color: ${props => props.theme.sidebarText};
color: ${(props) => props.theme.sidebarText};
font-size: 15px;
cursor: pointer;
&:hover {
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
}
&:focus {
color: ${props => props.theme.text};
background: ${props => props.theme.black05};
color: ${(props) => props.theme.text};
background: ${(props) => props.theme.black05};
outline: none;
}

View File

@ -71,13 +71,13 @@ class SocketProvider extends React.Component<Props> {
this.socket.authenticated = true;
});
this.socket.on("unauthorized", err => {
this.socket.on("unauthorized", (err) => {
this.socket.authenticated = false;
ui.showToast(err.message);
throw err;
});
this.socket.on("entities", async event => {
this.socket.on("entities", async (event) => {
if (event.documentIds) {
for (const documentDescriptor of event.documentIds) {
const documentId = documentDescriptor.id;
@ -182,23 +182,23 @@ class SocketProvider extends React.Component<Props> {
}
});
this.socket.on("documents.star", event => {
this.socket.on("documents.star", (event) => {
documents.starredIds.set(event.documentId, true);
});
this.socket.on("documents.unstar", event => {
this.socket.on("documents.unstar", (event) => {
documents.starredIds.set(event.documentId, false);
});
// received when a user is given access to a collection
// if the user is us then we go ahead and load the collection from API.
this.socket.on("collections.add_user", event => {
this.socket.on("collections.add_user", (event) => {
if (auth.user && event.userId === auth.user.id) {
collections.fetch(event.collectionId, { force: true });
}
// Document policies might need updating as the permission changes
documents.inCollection(event.collectionId).forEach(document => {
documents.inCollection(event.collectionId).forEach((document) => {
policies.remove(document.id);
});
});
@ -206,7 +206,7 @@ class SocketProvider extends React.Component<Props> {
// received when a user is removed from having access to a collection
// to keep state in sync we must update our UI if the user is us,
// or otherwise just remove any membership state we have for that user.
this.socket.on("collections.remove_user", event => {
this.socket.on("collections.remove_user", (event) => {
if (auth.user && event.userId === auth.user.id) {
collections.remove(event.collectionId);
memberships.removeCollectionMemberships(event.collectionId);
@ -218,32 +218,32 @@ class SocketProvider extends React.Component<Props> {
// received a message from the API server that we should request
// to join a specific room. Forward that to the ws server.
this.socket.on("join", event => {
this.socket.on("join", (event) => {
this.socket.emit("join", event);
});
// received a message from the API server that we should request
// to leave a specific room. Forward that to the ws server.
this.socket.on("leave", event => {
this.socket.on("leave", (event) => {
this.socket.emit("leave", event);
});
// received whenever we join a document room, the payload includes
// userIds that are present/viewing and those that are editing.
this.socket.on("document.presence", event => {
this.socket.on("document.presence", (event) => {
presence.init(event.documentId, event.userIds, event.editingIds);
});
// received whenever a new user joins a document room, aka they
// navigate to / start viewing a document
this.socket.on("user.join", event => {
this.socket.on("user.join", (event) => {
presence.touch(event.documentId, event.userId, event.isEditing);
views.touch(event.documentId, event.userId);
});
// received whenever a new user leaves a document room, aka they
// navigate away / stop viewing a document
this.socket.on("user.leave", event => {
this.socket.on("user.leave", (event) => {
presence.leave(event.documentId, event.userId);
views.touch(event.documentId, event.userId);
});
@ -251,7 +251,7 @@ class SocketProvider extends React.Component<Props> {
// received when another client in a document room wants to change
// or update it's presence. Currently the only property is whether
// the client is in editing state or not.
this.socket.on("user.presence", event => {
this.socket.on("user.presence", (event) => {
presence.touch(event.documentId, event.userId, event.isEditing);
});
}

View File

@ -7,7 +7,7 @@ type Props = {
};
const H3 = styled.h3`
border-bottom: 1px solid ${props => props.theme.divider};
border-bottom: 1px solid ${(props) => props.theme.divider};
margin-top: 22px;
margin-bottom: 12px;
line-height: 1;
@ -21,8 +21,8 @@ const Underline = styled("span")`
font-weight: 500;
font-size: 14px;
line-height: 1.5;
color: ${props => props.theme.textSecondary};
border-bottom: 3px solid ${props => props.theme.textSecondary};
color: ${(props) => props.theme.textSecondary};
border-bottom: 3px solid ${(props) => props.theme.textSecondary};
padding-bottom: 5px;
`;

View File

@ -38,8 +38,8 @@ const Label = styled.label`
const Wrapper = styled.label`
position: relative;
display: inline-block;
width: ${props => props.width}px;
height: ${props => props.height}px;
width: ${(props) => props.width}px;
height: ${(props) => props.height}px;
margin-bottom: 4px;
margin-right: 8px;
`;
@ -51,16 +51,16 @@ const Slider = styled.span`
left: 0;
right: 0;
bottom: 0;
background-color: ${props => props.theme.slate};
background-color: ${(props) => props.theme.slate};
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: ${props => props.height}px;
border-radius: ${(props) => props.height}px;
&:before {
position: absolute;
content: "";
height: ${props => props.height - 8}px;
width: ${props => props.height - 8}px;
height: ${(props) => props.height - 8}px;
width: ${(props) => props.height - 8}px;
left: 4px;
bottom: 4px;
background-color: white;
@ -77,15 +77,15 @@ const HiddenInput = styled.input`
visibility: hidden;
&:checked + ${Slider} {
background-color: ${props => props.theme.primary};
background-color: ${(props) => props.theme.primary};
}
&:focus + ${Slider} {
box-shadow: 0 0 1px ${props => props.theme.primary};
box-shadow: 0 0 1px ${(props) => props.theme.primary};
}
&:checked + ${Slider}:before {
transform: translateX(${props => props.width - props.height}px);
transform: translateX(${(props) => props.width - props.height}px);
}
`;

View File

@ -15,20 +15,20 @@ const StyledNavLink = styled(NavLink)`
display: inline-block;
font-weight: 500;
font-size: 14px;
color: ${props => props.theme.textTertiary};
color: ${(props) => props.theme.textTertiary};
margin-right: 24px;
padding-bottom: 8px;
&:hover {
color: ${props => props.theme.textSecondary};
border-bottom: 3px solid ${props => props.theme.divider};
color: ${(props) => props.theme.textSecondary};
border-bottom: 3px solid ${(props) => props.theme.divider};
padding-bottom: 5px;
}
&:focus {
outline: none;
border-bottom: 3px solid
${props => lighten(0.4, props.theme.buttonBackground)};
${(props) => lighten(0.4, props.theme.buttonBackground)};
padding-bottom: 5px;
}
`;

View File

@ -3,13 +3,13 @@ import styled from "styled-components";
const Tabs = styled.nav`
position: relative;
border-bottom: 1px solid ${props => props.theme.divider};
border-bottom: 1px solid ${(props) => props.theme.divider};
margin-top: 22px;
margin-bottom: 12px;
`;
export const Separator = styled.span`
border-left: 1px solid ${props => props.theme.divider};
border-left: 1px solid ${(props) => props.theme.divider};
position: relative;
top: 2px;
margin-right: 24px;

View File

@ -5,8 +5,8 @@ const TeamLogo = styled.img`
width: auto;
height: 38px;
border-radius: 4px;
background: ${props => props.theme.background};
border: 1px solid ${props => props.theme.divider};
background: ${(props) => props.theme.background};
border: 1px solid ${(props) => props.theme.divider};
`;
export default TeamLogo;

View File

@ -9,14 +9,14 @@ let callbacks = [];
// This is a shared timer that fires every minute, used for
// updating all Time components across the page all at once.
setInterval(() => {
callbacks.forEach(cb => cb());
callbacks.forEach((cb) => cb());
}, 1000 * 60);
function eachMinute(fn) {
callbacks.push(fn);
return () => {
callbacks = callbacks.filter(cb => cb !== fn);
callbacks = callbacks.filter((cb) => cb !== fn);
};
}

View File

@ -15,7 +15,7 @@ class Toasts extends React.Component<Props> {
return (
<List>
{ui.orderedToasts.map(toast => (
{ui.orderedToasts.map((toast) => (
<Toast
key={toast.id}
toast={toast}
@ -29,8 +29,8 @@ class Toasts extends React.Component<Props> {
const List = styled.ol`
position: fixed;
left: ${props => props.theme.hpadding};
bottom: ${props => props.theme.vpadding};
left: ${(props) => props.theme.hpadding};
bottom: ${(props) => props.theme.vpadding};
list-style: none;
margin: 0;
padding: 0;

View File

@ -61,13 +61,13 @@ const Action = styled.span`
height: 100%;
text-transform: uppercase;
font-size: 12px;
color: ${props => props.theme.toastText};
background: ${props => darken(0.05, props.theme.toastBackground)};
color: ${(props) => props.theme.toastText};
background: ${(props) => darken(0.05, props.theme.toastBackground)};
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
&:hover {
background: ${props => darken(0.1, props.theme.toastBackground)};
background: ${(props) => darken(0.1, props.theme.toastBackground)};
}
`;
@ -76,14 +76,14 @@ const Container = styled.div`
align-items: center;
animation: ${fadeAndScaleIn} 100ms ease;
margin: 8px 0;
color: ${props => props.theme.toastText};
background: ${props => props.theme.toastBackground};
color: ${(props) => props.theme.toastText};
background: ${(props) => props.theme.toastBackground};
font-size: 15px;
border-radius: 5px;
cursor: default;
&:hover {
background: ${props => darken(0.05, props.theme.toastBackground)};
background: ${(props) => darken(0.05, props.theme.toastBackground)};
}
`;

View File

@ -54,19 +54,19 @@ const Shortcut = styled.kbd`
font: 10px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier,
monospace;
line-height: 10px;
color: ${props => props.theme.tooltipBackground};
color: ${(props) => props.theme.tooltipBackground};
vertical-align: middle;
background-color: ${props => props.theme.tooltipText};
background-color: ${(props) => props.theme.tooltipText};
border-radius: 3px;
`;
const StyledTippy = styled(Tippy)`
font-size: 13px;
background-color: ${props => props.theme.tooltipBackground};
color: ${props => props.theme.tooltipText};
background-color: ${(props) => props.theme.tooltipBackground};
color: ${(props) => props.theme.tooltipText};
svg {
fill: ${props => props.theme.tooltipBackground};
fill: ${(props) => props.theme.tooltipBackground};
}
`;

View File

@ -19,9 +19,7 @@ export default class Figma extends React.Component<Props> {
render() {
return (
<Frame
src={`https://www.figma.com/embed?embed_host=outline&url=${
this.props.attrs.href
}`}
src={`https://www.figma.com/embed?embed_host=outline&url=${this.props.attrs.href}`}
title="Figma Embed"
border
/>

View File

@ -48,14 +48,10 @@ class Gist extends React.Component<Props> {
}
const gistLink = `https://gist.github.com/${id}.js`;
const gistScript = `<script type="text/javascript" src="${
gistLink
}"></script>`;
const gistScript = `<script type="text/javascript" src="${gistLink}"></script>`;
const styles =
"<style>*{ font-size:12px; } body { margin: 0; } .gist .blob-wrapper.data { max-height:150px; overflow:auto; }</style>";
const iframeHtml = `<html><head><base target="_parent">${
styles
}</head><body>${gistScript}</body></html>`;
const iframeHtml = `<html><head><base target="_parent">${styles}</head><body>${gistScript}</body></html>`;
doc.open();
doc.writeln(iframeHtml);
@ -67,7 +63,7 @@ class Gist extends React.Component<Props> {
return (
<iframe
ref={ref => {
ref={(ref) => {
this.iframeNode = ref;
}}
type="text/html"

View File

@ -65,17 +65,17 @@ class Frame extends React.Component<Props> {
const Rounded = styled.div`
border-radius: 3px;
overflow: hidden;
width: ${props => props.width};
height: ${props => props.height};
width: ${(props) => props.width};
height: ${(props) => props.height};
`;
// This wrapper allows us to pass non-standard HTML attributes through to the DOM element
// https://www.styled-components.com/docs/basics#passed-props
const Iframe = props => <iframe {...props} />;
const Iframe = (props) => <iframe {...props} />;
const StyledIframe = styled(Iframe)`
border: 1px solid;
border-color: ${props => props.theme.embedBorder};
border-color: ${(props) => props.theme.embedBorder};
border-radius: 3px;
`;

View File

@ -97,9 +97,9 @@ class CollectionMenu extends React.Component<Props> {
<VisuallyHidden>
<input
type="file"
ref={ref => (this.file = ref)}
ref={(ref) => (this.file = ref)}
onChange={this.onFilePicked}
onClick={ev => ev.stopPropagation()}
onClick={(ev) => ev.stopPropagation()}
accept="text/markdown, text/plain"
/>
</VisuallyHidden>
@ -153,6 +153,8 @@ class CollectionMenu extends React.Component<Props> {
}
}
export default inject("ui", "documents", "policies")(
withRouter(CollectionMenu)
);
export default inject(
"ui",
"documents",
"policies"
)(withRouter(CollectionMenu));

View File

@ -219,12 +219,11 @@ class DocumentMenu extends React.Component<Props> {
New nested document
</DropdownMenuItem>
)}
{can.update &&
!document.isTemplate && (
<DropdownMenuItem onClick={this.handleOpenTemplateModal}>
Create template
</DropdownMenuItem>
)}
{can.update && !document.isTemplate && (
<DropdownMenuItem onClick={this.handleOpenTemplateModal}>
Create template
</DropdownMenuItem>
)}
{can.update && (
<DropdownMenuItem onClick={this.handleEdit}>Edit</DropdownMenuItem>
)}

View File

@ -63,7 +63,7 @@ class NewDocumentMenu extends React.Component<Props> {
{...rest}
>
<Header>Choose a collection</Header>
{collections.orderedData.map(collection => {
{collections.orderedData.map((collection) => {
const can = policies.abilities(collection.id);
return (
@ -72,7 +72,8 @@ class NewDocumentMenu extends React.Component<Props> {
onClick={() => this.handleNewDocument(collection.id)}
disabled={!can.update}
>
<CollectionIcon collection={collection} />&nbsp;{collection.name}
<CollectionIcon collection={collection} />
&nbsp;{collection.name}
</DropdownMenuItem>
);
})}

View File

@ -53,7 +53,7 @@ class NewTemplateMenu extends React.Component<Props> {
{...rest}
>
<Header>Choose a collection</Header>
{collections.orderedData.map(collection => {
{collections.orderedData.map((collection) => {
const can = policies.abilities(collection.id);
return (
@ -62,7 +62,8 @@ class NewTemplateMenu extends React.Component<Props> {
onClick={() => this.handleNewDocument(collection.id)}
disabled={!can.update}
>
<CollectionIcon collection={collection} />&nbsp;{collection.name}
<CollectionIcon collection={collection} />
&nbsp;{collection.name}
</DropdownMenuItem>
);
})}

View File

@ -33,7 +33,7 @@ class TemplatesMenu extends React.Component<Props> {
}
{...rest}
>
{templates.map(template => (
{templates.map((template) => (
<DropdownMenuItem
key={template.id}
onClick={() => document.updateFromTemplate(template)}

View File

@ -18,9 +18,7 @@ class UserMenu extends React.Component<Props> {
const { user, users } = this.props;
if (
!window.confirm(
`Are you want to make ${
user.name
} an admin? Admins can modify team and billing information.`
`Are you want to make ${user.name} an admin? Admins can modify team and billing information.`
)
) {
return;
@ -72,12 +70,11 @@ class UserMenu extends React.Component<Props> {
Make {user.name} a member
</DropdownMenuItem>
)}
{!user.isAdmin &&
!user.isSuspended && (
<DropdownMenuItem onClick={this.handlePromote}>
Make {user.name} an admin
</DropdownMenuItem>
)}
{!user.isAdmin && !user.isSuspended && (
<DropdownMenuItem onClick={this.handlePromote}>
Make {user.name} an admin
</DropdownMenuItem>
)}
{!user.lastActiveAt && (
<DropdownMenuItem onClick={this.handleRevoke}>
Revoke invite

View File

@ -11,7 +11,7 @@ export default class BaseModel {
this.store = store;
}
save = async params => {
save = async (params) => {
this.isSaving = true;
try {

View File

@ -37,7 +37,7 @@ export default class Collection extends BaseModel {
get documentIds(): string[] {
const results = [];
const travelDocuments = (documentList, path) =>
documentList.forEach(document => {
documentList.forEach((document) => {
results.push(document.id);
travelDocuments(document.children);
});
@ -49,7 +49,7 @@ export default class Collection extends BaseModel {
@action
updateDocument(document: Document) {
const travelDocuments = (documentList, path) =>
documentList.forEach(d => {
documentList.forEach((d) => {
if (d.id === document.id) {
d.title = document.title;
d.url = document.url;
@ -63,8 +63,8 @@ export default class Collection extends BaseModel {
getDocumentChildren(documentId: string): NavigationNode[] {
let result = [];
const traveler = nodes => {
nodes.forEach(childNode => {
const traveler = (nodes) => {
nodes.forEach((childNode) => {
if (childNode.id === documentId) {
result = childNode.children;
return;
@ -83,7 +83,7 @@ export default class Collection extends BaseModel {
pathToDocument(document: Document) {
let path;
const traveler = (nodes, previousPath) => {
nodes.forEach(childNode => {
nodes.forEach((childNode) => {
const newPath = [...previousPath, childNode];
if (childNode.id === document.id) {
path = newPath;

View File

@ -133,7 +133,7 @@ export default class Document extends BaseModel {
};
@action
updateFromJson = data => {
updateFromJson = (data) => {
set(this, data);
};
@ -253,11 +253,7 @@ export default class Document extends BaseModel {
};
getSummary = (paragraphs: number = 4) => {
const result = this.text
.trim()
.split("\n")
.slice(0, paragraphs)
.join("\n");
const result = this.text.trim().split("\n").slice(0, paragraphs).join("\n");
return result;
};

View File

@ -171,14 +171,17 @@ class CollectionScene extends React.Component<Props> {
<Centered column>
<HelpText>
<strong>{collection.name}</strong> doesnt contain any
documents yet.<br />Get started by creating a new one!
documents yet.
<br />
Get started by creating a new one!
</HelpText>
<Wrapper>
<Link to={newDocumentUrl(collection.id)}>
<Button icon={<NewDocumentIcon color={theme.buttonText} />}>
Create a document
</Button>
</Link>&nbsp;&nbsp;
</Link>
&nbsp;&nbsp;
{collection.private && (
<Button onClick={this.onPermissions} neutral>
Manage members
@ -329,6 +332,9 @@ const Wrapper = styled(Flex)`
margin: 10px 0;
`;
export default inject("collections", "policies", "documents", "ui")(
withTheme(CollectionScene)
);
export default inject(
"collections",
"policies",
"documents",
"ui"
)(withTheme(CollectionScene));

View File

@ -56,7 +56,7 @@ class CollectionEdit extends React.Component<Props> {
}
};
handleDescriptionChange = getValue => {
handleDescriptionChange = (getValue) => {
this.description = getValue();
};

View File

@ -52,7 +52,7 @@ class AddGroupsToCollection extends React.Component<Props> {
});
}, 250);
handleAddGroup = group => {
handleAddGroup = (group) => {
try {
this.props.collectionGroupMemberships.create({
collectionId: this.props.collection.id,
@ -77,7 +77,8 @@ class AddGroupsToCollection extends React.Component<Props> {
Cant find the group youre looking for?{" "}
<a role="button" onClick={this.handleNewGroupModalOpen}>
Create a group
</a>.
</a>
.
</HelpText>
<Input
@ -99,7 +100,7 @@ class AddGroupsToCollection extends React.Component<Props> {
}
items={groups.notInCollection(collection.id, this.query)}
fetch={this.query ? undefined : groups.fetchPage}
renderItem={item => (
renderItem={(item) => (
<GroupListItem
key={item.id}
group={item}
@ -130,6 +131,9 @@ const ButtonWrap = styled.div`
margin-left: 6px;
`;
export default inject("auth", "groups", "collectionGroupMemberships", "ui")(
AddGroupsToCollection
);
export default inject(
"auth",
"groups",
"collectionGroupMemberships",
"ui"
)(AddGroupsToCollection);

View File

@ -50,7 +50,7 @@ class AddPeopleToCollection extends React.Component<Props> {
});
}, 250);
handleAddUser = user => {
handleAddUser = (user) => {
try {
this.props.memberships.create({
collectionId: this.props.collection.id,
@ -74,7 +74,8 @@ class AddPeopleToCollection extends React.Component<Props> {
Need to add someone whos not yet on the team yet?{" "}
<a role="button" onClick={this.handleInviteModalOpen}>
Invite people to {team.name}
</a>.
</a>
.
</HelpText>
<Input
@ -97,7 +98,7 @@ class AddPeopleToCollection extends React.Component<Props> {
}
items={users.notInCollection(collection.id, this.query)}
fetch={this.query ? undefined : users.fetchPage}
renderItem={item => (
renderItem={(item) => (
<MemberListItem
key={item.id}
user={item}
@ -118,6 +119,9 @@ class AddPeopleToCollection extends React.Component<Props> {
}
}
export default inject("auth", "users", "memberships", "ui")(
AddPeopleToCollection
);
export default inject(
"auth",
"users",
"memberships",
"ui"
)(AddPeopleToCollection);

View File

@ -55,7 +55,7 @@ class CollectionMembers extends React.Component<Props> {
this.addMemberModalOpen = false;
};
handleRemoveUser = user => {
handleRemoveUser = (user) => {
try {
this.props.memberships.delete({
collectionId: this.props.collection.id,
@ -80,7 +80,7 @@ class CollectionMembers extends React.Component<Props> {
}
};
handleRemoveGroup = group => {
handleRemoveGroup = (group) => {
try {
this.props.collectionGroupMemberships.delete({
collectionId: this.props.collection.id,
@ -118,7 +118,7 @@ class CollectionMembers extends React.Component<Props> {
if (!user) return null;
const key = memberships.orderedData
.map(m => m.permission)
.map((m) => m.permission)
.concat(collection.private)
.join("-");
@ -133,7 +133,8 @@ class CollectionMembers extends React.Component<Props> {
team by{" "}
<a role="button" onClick={this.props.onEdit}>
changing its visibility
</a>.
</a>
.
</HelpText>
<span>
<Button
@ -153,7 +154,8 @@ class CollectionMembers extends React.Component<Props> {
collection,{" "}
<a role="button" onClick={this.props.onEdit}>
make it private
</a>.
</a>
.
</HelpText>
)}
@ -166,7 +168,7 @@ class CollectionMembers extends React.Component<Props> {
fetch={collectionGroupMemberships.fetchPage}
options={collection.private ? { id: collection.id } : undefined}
empty={<Empty>This collection has no groups.</Empty>}
renderItem={group => (
renderItem={(group) => (
<CollectionGroupMemberListItem
key={group.id}
group={group}
@ -174,7 +176,7 @@ class CollectionMembers extends React.Component<Props> {
`${group.id}-${collection.id}`
)}
onRemove={() => this.handleRemoveGroup(group)}
onUpdate={permission =>
onUpdate={(permission) =>
this.handleUpdateGroup(group, permission)
}
/>
@ -219,14 +221,14 @@ class CollectionMembers extends React.Component<Props> {
}
fetch={collection.private ? memberships.fetchPage : users.fetchPage}
options={collection.private ? { id: collection.id } : undefined}
renderItem={item => (
renderItem={(item) => (
<MemberListItem
key={item.id}
user={item}
membership={memberships.get(`${item.id}-${collection.id}`)}
canEdit={collection.private && item.id !== user.id}
onRemove={() => this.handleRemoveUser(item)}
onUpdate={permission => this.handleUpdateUser(item, permission)}
onUpdate={(permission) => this.handleUpdateUser(item, permission)}
/>
)}
/>

View File

@ -39,7 +39,7 @@ const MemberListItem = ({
? collectionGroupMembership.permission
: undefined
}
onChange={ev => onUpdate(ev.target.value)}
onChange={(ev) => onUpdate(ev.target.value)}
labelHidden
/>
<ButtonWrap>

View File

@ -52,29 +52,26 @@ const MemberListItem = ({
image={<Avatar src={user.avatarUrl} size={40} />}
actions={
<Flex align="center">
{canEdit &&
onUpdate && (
<Select
label="Permissions"
options={PERMISSIONS}
value={membership ? membership.permission : undefined}
onChange={ev => onUpdate(ev.target.value)}
labelHidden
/>
)}
{canEdit && onUpdate && (
<Select
label="Permissions"
options={PERMISSIONS}
value={membership ? membership.permission : undefined}
onChange={(ev) => onUpdate(ev.target.value)}
labelHidden
/>
)}
&nbsp;&nbsp;
{canEdit &&
onRemove && (
<DropdownMenu>
<DropdownMenuItem onClick={onRemove}>Remove</DropdownMenuItem>
</DropdownMenu>
)}
{canEdit &&
onAdd && (
<Button onClick={onAdd} neutral>
Add
</Button>
)}
{canEdit && onRemove && (
<DropdownMenu>
<DropdownMenuItem onClick={onRemove}>Remove</DropdownMenuItem>
</DropdownMenu>
)}
{canEdit && onAdd && (
<Button onClick={onAdd} neutral>
Add
</Button>
)}
</Flex>
}
/>

View File

@ -37,9 +37,7 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
<Button type="button" onClick={onAdd} icon={<PlusIcon />} neutral>
Add
</Button>
) : (
undefined
)
) : undefined
}
/>
);

View File

@ -85,7 +85,7 @@ class CollectionNew extends React.Component<Props> {
this.hasOpenedIconPicker = true;
};
handleDescriptionChange = getValue => {
handleDescriptionChange = (getValue) => {
this.description = getValue();
};

View File

@ -4,7 +4,7 @@ import Flex from "components/Flex";
const Container = styled(Flex)`
position: relative;
margin-top: ${props => (props.isShare ? "50px" : "0")};
margin-top: ${(props) => (props.isShare ? "50px" : "0")};
`;
export default Container;

View File

@ -16,26 +16,23 @@ export default function Contents({ headings }: Props) {
const [activeSlug, setActiveSlug] = React.useState();
const position = useWindowScrollPosition({ throttle: 100 });
React.useEffect(
() => {
for (let key = 0; key < headings.length; key++) {
const heading = headings[key];
const element = window.document.getElementById(
decodeURIComponent(heading.id)
);
React.useEffect(() => {
for (let key = 0; key < headings.length; key++) {
const heading = headings[key];
const element = window.document.getElementById(
decodeURIComponent(heading.id)
);
if (element) {
const bounding = element.getBoundingClientRect();
if (bounding.top > HEADING_OFFSET) {
const last = headings[Math.max(0, key - 1)];
setActiveSlug(last.id);
return;
}
if (element) {
const bounding = element.getBoundingClientRect();
if (bounding.top > HEADING_OFFSET) {
const last = headings[Math.max(0, key - 1)];
setActiveSlug(last.id);
return;
}
}
},
[position, headings]
);
}
}, [position, headings]);
// calculate the minimum heading level and adjust all the headings to make
// that the top-most. This prevents the contents from being weirdly indented
@ -52,7 +49,7 @@ export default function Contents({ headings }: Props) {
<Heading>Contents</Heading>
{headings.length ? (
<List>
{headings.map(heading => (
{headings.map((heading) => (
<ListItem
key={heading.id}
level={heading.level - headingAdjustment}
@ -75,7 +72,7 @@ const Wrapper = styled("div")`
position: sticky;
top: 80px;
box-shadow: 1px 0 0 ${props => darken(0.05, props.theme.sidebarBackground)};
box-shadow: 1px 0 0 ${(props) => darken(0.05, props.theme.sidebarBackground)};
margin-top: 40px;
margin-right: 2em;
min-height: 40px;
@ -93,7 +90,7 @@ const Heading = styled("h3")`
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: ${props => props.theme.sidebarText};
color: ${(props) => props.theme.sidebarText};
letter-spacing: 0.04em;
`;
@ -106,20 +103,20 @@ const Empty = styled(HelpText)`
`;
const ListItem = styled("li")`
margin-left: ${props => (props.level - 1) * 10}px;
margin-left: ${(props) => (props.level - 1) * 10}px;
margin-bottom: 8px;
padding-right: 2em;
line-height: 1.3;
border-right: 3px solid
${props => (props.active ? props.theme.textSecondary : "transparent")};
${(props) => (props.active ? props.theme.textSecondary : "transparent")};
`;
const Link = styled("a")`
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
font-size: 14px;
&:hover {
color: ${props => props.theme.primary};
color: ${(props) => props.theme.primary};
}
`;

View File

@ -77,7 +77,7 @@ class DataLoader extends React.Component<Props> {
const results = await this.props.documents.search(term);
return results
.filter(result => result.document.title)
.filter((result) => result.document.title)
.map((result, index) => ({
title: result.document.title,
url: result.document.url,
@ -130,7 +130,7 @@ class DataLoader extends React.Component<Props> {
return this.goToDocumentCanonical();
}
this.props.shares.fetch(document.id).catch(err => {
this.props.shares.fetch(document.id).catch((err) => {
if (!(err instanceof NotFoundError)) {
throw err;
}
@ -195,7 +195,12 @@ class DataLoader extends React.Component<Props> {
}
export default withRouter(
inject("ui", "auth", "documents", "revisions", "policies", "shares")(
DataLoader
)
inject(
"ui",
"auth",
"documents",
"revisions",
"policies",
"shares"
)(DataLoader)
);

View File

@ -298,7 +298,7 @@ class DocumentScene extends React.Component<Props> {
this.isUploading = false;
};
onChange = getEditorText => {
onChange = (getEditorText) => {
this.getEditorText = getEditorText;
// document change while read only is presumed to be a checkbox edit,
@ -312,7 +312,7 @@ class DocumentScene extends React.Component<Props> {
}
};
onChangeTitle = event => {
onChangeTitle = (event) => {
this.title = event.target.value;
this.updateIsDirtyDebounced();
this.autosave();
@ -409,22 +409,20 @@ class DocumentScene extends React.Component<Props> {
column
auto
>
{document.isTemplate &&
!readOnly && (
<Notice muted>
Youre editing a template. Highlight some text and use the{" "}
<PlaceholderIcon color="currentColor" /> control to add
placeholders that can be filled out when creating new
documents from this template.
</Notice>
)}
{document.archivedAt &&
!document.deletedAt && (
<Notice muted>
Archived by {document.updatedBy.name}{" "}
<Time dateTime={document.archivedAt} /> ago
</Notice>
)}
{document.isTemplate && !readOnly && (
<Notice muted>
Youre editing a template. Highlight some text and use the{" "}
<PlaceholderIcon color="currentColor" /> control to add
placeholders that can be filled out when creating new
documents from this template.
</Notice>
)}
{document.archivedAt && !document.deletedAt && (
<Notice muted>
Archived by {document.updatedBy.name}{" "}
<Time dateTime={document.archivedAt} /> ago
</Notice>
)}
{document.deletedAt && (
<Notice muted>
Deleted by {document.updatedBy.name}{" "}
@ -440,15 +438,14 @@ class DocumentScene extends React.Component<Props> {
</Notice>
)}
<Flex auto={!readOnly}>
{ui.tocVisible &&
readOnly && (
<Contents
headings={this.editor ? this.editor.getHeadings() : []}
/>
)}
{ui.tocVisible && readOnly && (
<Contents
headings={this.editor ? this.editor.getHeadings() : []}
/>
)}
<Editor
id={document.id}
ref={ref => {
ref={(ref) => {
if (ref) {
this.editor = ref;
}
@ -476,16 +473,14 @@ class DocumentScene extends React.Component<Props> {
ui={this.props.ui}
/>
</Flex>
{readOnly &&
!isShare &&
!revision && (
<React.Fragment>
<MarkAsViewed document={document} />
<ReferencesWrapper isOnlyTitle={document.isOnlyTitle}>
<References document={document} />
</ReferencesWrapper>
</React.Fragment>
)}
{readOnly && !isShare && !revision && (
<React.Fragment>
<MarkAsViewed document={document} />
<ReferencesWrapper isOnlyTitle={document.isOnlyTitle}>
<References document={document} />
</ReferencesWrapper>
</React.Fragment>
)}
</MaxWidth>
</Container>
</Background>
@ -501,12 +496,12 @@ const PlaceholderIcon = styled(InputIcon)`
`;
const Background = styled(Container)`
background: ${props => props.theme.background};
transition: ${props => props.theme.backgroundTransition};
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
`;
const ReferencesWrapper = styled("div")`
margin-top: ${props => (props.isOnlyTitle ? -45 : 16)}px;
margin-top: ${(props) => (props.isOnlyTitle ? -45 : 16)}px;
@media print {
display: none;
@ -514,7 +509,7 @@ const ReferencesWrapper = styled("div")`
`;
const MaxWidth = styled(Flex)`
${props =>
${(props) =>
props.archived && `* { color: ${props.theme.textSecondary} !important; } `};
padding: 0 16px;
max-width: 100vw;
@ -523,7 +518,7 @@ const MaxWidth = styled(Flex)`
${breakpoint("tablet")`
padding: 0 24px;
margin: 4px auto 12px;
max-width: calc(48px + ${props => (props.tocVisible ? "64em" : "46em")});
max-width: calc(48px + ${(props) => (props.tocVisible ? "64em" : "46em")});
`};
${breakpoint("desktopLarge")`

View File

@ -44,7 +44,7 @@ class DocumentMove extends React.Component<Props> {
// Build index
const indexeableDocuments = [];
paths.forEach(path => indexeableDocuments.push(path));
paths.forEach((path) => indexeableDocuments.push(path));
index.addDocuments(indexeableDocuments);
return index;
@ -65,20 +65,20 @@ class DocumentMove extends React.Component<Props> {
// Exclude root from search results if document is already at the root
if (!document.parentDocumentId) {
results = results.filter(result => result.id !== document.collectionId);
results = results.filter((result) => result.id !== document.collectionId);
}
// Exclude document if on the path to result, or the same result
results = results.filter(
result =>
!result.path.map(doc => doc.id).includes(document.id) &&
last(result.path.map(doc => doc.id)) !== document.parentDocumentId
(result) =>
!result.path.map((doc) => doc.id).includes(document.id) &&
last(result.path.map((doc) => doc.id)) !== document.parentDocumentId
);
return results;
}
handleKeyDown = ev => {
handleKeyDown = (ev) => {
// Down
if (ev.which === 40) {
ev.preventDefault();
@ -98,7 +98,7 @@ class DocumentMove extends React.Component<Props> {
this.searchTerm = ev.target.value;
};
setFirstDocumentRef = ref => {
setFirstDocumentRef = (ref) => {
this.firstDocument = ref;
};
@ -121,50 +121,47 @@ class DocumentMove extends React.Component<Props> {
return (
<Modal isOpen onRequestClose={onRequestClose} title="Move document">
{document &&
collections.isLoaded && (
<Flex column>
<Section>
<Labeled label="Current location">
{this.renderPathToCurrentDocument()}
</Labeled>
</Section>
{document && collections.isLoaded && (
<Flex column>
<Section>
<Labeled label="Current location">
{this.renderPathToCurrentDocument()}
</Labeled>
</Section>
<Section column>
<Labeled label="Choose a new location">
<Input
type="search"
placeholder="Search collections & documents…"
onKeyDown={this.handleKeyDown}
onChange={this.handleFilter}
required
autoFocus
/>
</Labeled>
<Flex column>
<StyledArrowKeyNavigation
mode={ArrowKeyNavigation.mode.VERTICAL}
defaultActiveChildIndex={0}
>
{this.results
.slice(0, MAX_RESULTS)
.map((result, index) => (
<PathToDocument
key={result.id}
result={result}
document={document}
collection={collections.get(result.collectionId)}
ref={ref =>
index === 0 && this.setFirstDocumentRef(ref)
}
onSuccess={this.handleSuccess}
/>
))}
</StyledArrowKeyNavigation>
</Flex>
</Section>
</Flex>
)}
<Section column>
<Labeled label="Choose a new location">
<Input
type="search"
placeholder="Search collections & documents…"
onKeyDown={this.handleKeyDown}
onChange={this.handleFilter}
required
autoFocus
/>
</Labeled>
<Flex column>
<StyledArrowKeyNavigation
mode={ArrowKeyNavigation.mode.VERTICAL}
defaultActiveChildIndex={0}
>
{this.results.slice(0, MAX_RESULTS).map((result, index) => (
<PathToDocument
key={result.id}
result={result}
document={document}
collection={collections.get(result.collectionId)}
ref={(ref) =>
index === 0 && this.setFirstDocumentRef(ref)
}
onSuccess={this.handleSuccess}
/>
))}
</StyledArrowKeyNavigation>
</Flex>
</Section>
</Flex>
)}
</Modal>
);
}

View File

@ -89,7 +89,7 @@ class DocumentEditor extends React.Component<Props> {
/>
<DocumentMeta isDraft={isDraft} document={document} />
<Editor
ref={ref => (this.editor = ref)}
ref={(ref) => (this.editor = ref)}
autoFocus={title && !this.props.defaultValue}
placeholder="…the rest is up to you"
onHoverLink={this.handleLinkActive}
@ -98,15 +98,13 @@ class DocumentEditor extends React.Component<Props> {
{...this.props}
/>
{!readOnly && <ClickablePadding onClick={this.focusAtEnd} grow />}
{this.activeLinkEvent &&
!isShare &&
readOnly && (
<HoverPreview
node={this.activeLinkEvent.target}
event={this.activeLinkEvent}
onClose={this.handleLinkInactive}
/>
)}
{this.activeLinkEvent && !isShare && readOnly && (
<HoverPreview
node={this.activeLinkEvent.target}
event={this.activeLinkEvent}
onClose={this.handleLinkInactive}
/>
)}
</Flex>
);
}
@ -117,10 +115,10 @@ const Title = styled(Textarea)`
line-height: 1.25;
margin-top: 1em;
margin-bottom: 0.5em;
text: ${props => props.theme.text};
background: ${props => props.theme.background};
transition: ${props => props.theme.backgroundTransition};
color: ${props => props.theme.text};
text: ${(props) => props.theme.text};
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
color: ${(props) => props.theme.text};
font-size: 2.25em;
font-weight: 500;
outline: none;
@ -129,7 +127,7 @@ const Title = styled(Textarea)`
resize: none;
&::placeholder {
color: ${props => props.theme.placeholder};
color: ${(props) => props.theme.placeholder};
}
`;

View File

@ -194,12 +194,11 @@ class Header extends React.Component<Props> {
</Title>
)}
<Wrapper align="center" justify="flex-end">
{isSaving &&
!isPublishing && (
<Action>
<Status>Saving</Status>
</Action>
)}
{isSaving && !isPublishing && (
<Action>
<Status>Saving</Status>
</Action>
)}
&nbsp;
<Fade>
<Collaborators
@ -207,40 +206,38 @@ class Header extends React.Component<Props> {
currentUserId={auth.user ? auth.user.id : undefined}
/>
</Fade>
{isEditing &&
!isTemplate &&
isNew && (
<Action>
<TemplatesMenu document={document} />
</Action>
)}
{!isEditing &&
canShareDocuments && (
<Action>
<Tooltip
tooltip={
isPubliclyShared ? (
<React.Fragment>
Anyone with the link <br />can view this document
</React.Fragment>
) : (
""
)
}
delay={500}
placement="bottom"
{isEditing && !isTemplate && isNew && (
<Action>
<TemplatesMenu document={document} />
</Action>
)}
{!isEditing && canShareDocuments && (
<Action>
<Tooltip
tooltip={
isPubliclyShared ? (
<React.Fragment>
Anyone with the link <br />
can view this document
</React.Fragment>
) : (
""
)
}
delay={500}
placement="bottom"
>
<Button
icon={isPubliclyShared ? <GlobeIcon /> : undefined}
onClick={this.handleShareLink}
neutral
small
>
<Button
icon={isPubliclyShared ? <GlobeIcon /> : undefined}
onClick={this.handleShareLink}
neutral
small
>
Share
</Button>
</Tooltip>
</Action>
)}
Share
</Button>
</Tooltip>
</Action>
)}
{isEditing && (
<React.Fragment>
<Action>
@ -282,62 +279,56 @@ class Header extends React.Component<Props> {
</Tooltip>
</Action>
)}
{canEdit &&
can.createChildDocument && (
<Action>
<NewChildDocumentMenu
document={document}
label={
<Tooltip
tooltip="New document"
shortcut="n"
delay={500}
placement="bottom"
>
<Button icon={<PlusIcon />} neutral>
New doc
</Button>
</Tooltip>
}
/>
</Action>
)}
{canEdit &&
isTemplate &&
!isDraft &&
!isRevision && (
<Action>
{canEdit && can.createChildDocument && (
<Action>
<NewChildDocumentMenu
document={document}
label={
<Tooltip
tooltip="New document"
shortcut="n"
delay={500}
placement="bottom"
>
<Button icon={<PlusIcon />} neutral>
New doc
</Button>
</Tooltip>
}
/>
</Action>
)}
{canEdit && isTemplate && !isDraft && !isRevision && (
<Action>
<Button
icon={<PlusIcon />}
onClick={this.handleNewFromTemplate}
primary
small
>
New from template
</Button>
</Action>
)}
{can.update && isDraft && !isRevision && (
<Action>
<Tooltip
tooltip="Publish"
shortcut={`${meta}+shift+p`}
delay={500}
placement="bottom"
>
<Button
icon={<PlusIcon />}
onClick={this.handleNewFromTemplate}
primary
onClick={this.handlePublish}
title="Publish document"
disabled={publishingIsDisabled}
small
>
New from template
{isPublishing ? "Publishing…" : "Publish"}
</Button>
</Action>
)}
{can.update &&
isDraft &&
!isRevision && (
<Action>
<Tooltip
tooltip="Publish"
shortcut={`${meta}+shift+p`}
delay={500}
placement="bottom"
>
<Button
onClick={this.handlePublish}
title="Publish document"
disabled={publishingIsDisabled}
small
>
{isPublishing ? "Publishing…" : "Publish"}
</Button>
</Tooltip>
</Action>
)}
</Tooltip>
</Action>
)}
{!isEditing && (
<React.Fragment>
<Separator />
@ -358,7 +349,7 @@ class Header extends React.Component<Props> {
}
const Status = styled.div`
color: ${props => props.theme.slate};
color: ${(props) => props.theme.slate};
`;
const BreadcrumbAndContents = styled(Flex)`
@ -386,9 +377,9 @@ const Actions = styled(Flex)`
right: 0;
left: 0;
z-index: 2;
background: ${props => transparentize(0.2, props.theme.background)};
background: ${(props) => transparentize(0.2, props.theme.background)};
box-shadow: 0 1px 0
${props =>
${(props) =>
props.isCompact
? darken(0.05, props.theme.sidebarBackground)
: "transparent"};
@ -402,7 +393,7 @@ const Actions = styled(Flex)`
}
${breakpoint("tablet")`
padding: ${props => (props.isCompact ? "12px" : `24px 24px 0`)};
padding: ${(props) => (props.isCompact ? "12px" : `24px 24px 0`)};
`};
`;

View File

@ -26,7 +26,7 @@ const DocumentLink = styled(Link)`
&:hover,
&:active,
&:focus {
background: ${props => props.theme.listItemHoverBackground};
background: ${(props) => props.theme.listItemHoverBackground};
outline: none;
}
`;
@ -39,7 +39,7 @@ const Title = styled.h3`
margin-top: 0;
margin-bottom: 0.25em;
white-space: nowrap;
color: ${props => props.theme.text};
color: ${(props) => props.theme.text};
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
`;

View File

@ -52,7 +52,7 @@ class References extends React.Component<Props> {
)}
</Tabs>
{isBacklinksTab
? backlinks.map(backlinkedDocument => (
? backlinks.map((backlinkedDocument) => (
<ReferenceListItem
anchor={document.urlId}
key={backlinkedDocument.id}
@ -62,7 +62,7 @@ class References extends React.Component<Props> {
}
/>
))
: children.map(node => {
: children.map((node) => {
// If we have the document in the store already then use it to get the extra
// contextual info, otherwise the collection node will do (only has title and id)
const document = documents.get(node.id);

View File

@ -51,17 +51,15 @@ class DocumentDelete extends React.Component<Props> {
<HelpText>
Are you sure about that? Deleting the{" "}
<strong>{document.titleWithDefault}</strong> {document.noun} will
delete all of its history{document.isTemplate
? ""
: ", and any nested documents"}.
delete all of its history
{document.isTemplate ? "" : ", and any nested documents"}.
</HelpText>
{!document.isDraft &&
!document.isArchived && (
<HelpText>
If youd like the option of referencing or restoring this{" "}
{document.noun} in the future, consider archiving it instead.
</HelpText>
)}
{!document.isDraft && !document.isArchived && (
<HelpText>
If youd like the option of referencing or restoring this{" "}
{document.noun} in the future, consider archiving it instead.
</HelpText>
)}
<Button type="submit" danger>
{this.isDeleting ? "Deleting…" : "Im sure  Delete"}
</Button>

View File

@ -35,7 +35,7 @@ class DocumentShare extends React.Component<Props> {
clearTimeout(this.timeout);
}
handlePublishedChange = async event => {
handlePublishedChange = async (event) => {
const { document, shares } = this.props;
const share = shares.getByDocumentId(document.id);
invariant(share, "Share must exist");
@ -76,7 +76,8 @@ class DocumentShare extends React.Component<Props> {
: "It is only viewable by those that already have access to the collection."}{" "}
<Link to="/settings/shares" onClick={onSubmit}>
Manage all share links
</Link>.
</Link>
.
</HelpText>
{canPublish && (
<React.Fragment>
@ -112,7 +113,9 @@ class DocumentShare extends React.Component<Props> {
<Button type="submit" disabled={this.isCopied || !share} primary>
{this.isCopied ? "Copied!" : "Copy Link"}
</Button>
</CopyToClipboard>&nbsp;&nbsp;&nbsp;<a href={share.url} target="_blank">
</CopyToClipboard>
&nbsp;&nbsp;&nbsp;
<a href={share.url} target="_blank">
Preview
</a>
</div>

View File

@ -10,9 +10,8 @@ const Error404 = () => {
<PageTitle title="Not Found" />
<h1>Not found</h1>
<Empty>
We were unable to find the page youre looking for. Go to the&nbsp;<a href="/">
homepage
</a>?
We were unable to find the page youre looking for. Go to the&nbsp;
<a href="/">homepage</a>?
</Empty>
</CenteredContent>
);

View File

@ -50,7 +50,7 @@ class AddPeopleToGroup extends React.Component<Props> {
});
}, 250);
handleAddUser = async user => {
handleAddUser = async (user) => {
try {
await this.props.groupMemberships.create({
groupId: this.props.group.id,
@ -74,7 +74,8 @@ class AddPeopleToGroup extends React.Component<Props> {
someone whos not yet on the team yet?{" "}
<a role="button" onClick={this.handleInviteModalOpen}>
Invite them to {team.name}
</a>.
</a>
.
</HelpText>
<Input
@ -97,7 +98,7 @@ class AddPeopleToGroup extends React.Component<Props> {
}
items={users.notInGroup(group.id, this.query)}
fetch={this.query ? undefined : users.fetchPage}
renderItem={item => (
renderItem={(item) => (
<GroupMemberListItem
key={item.id}
user={item}
@ -118,6 +119,9 @@ class AddPeopleToGroup extends React.Component<Props> {
}
}
export default inject("auth", "users", "groupMemberships", "ui")(
AddPeopleToGroup
);
export default inject(
"auth",
"users",
"groupMemberships",
"ui"
)(AddPeopleToGroup);

Some files were not shown because too many files have changed in this diff Show More