chore: Upgrade Prettier 1.8 -> 2.0 (#1436)
This commit is contained in:
parent
68dcb4de5f
commit
e312b264a6
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ type Props = {
|
|||
function Branding({ href = env.URL }: Props) {
|
||||
return (
|
||||
<Link href={href}>
|
||||
<OutlineLogo size={16} /> Outline
|
||||
<OutlineLogo size={16} />
|
||||
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};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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" />
|
||||
<ShapesIcon color="currentColor" />
|
||||
|
||||
<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" />
|
||||
<EditIcon color="currentColor" />
|
||||
|
||||
<span>Drafts</span>
|
||||
</CollectionName>
|
||||
<Slash />
|
||||
</React.Fragment>
|
||||
)}
|
||||
<CollectionName to={collectionUrl(collection.id)}>
|
||||
<CollectionIcon collection={collection} expanded />
|
||||
<CollectionIcon collection={collection} expanded />
|
||||
|
||||
<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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
)}
|
||||
|
||||
<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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -29,7 +29,8 @@ const DropdownMenuItem = ({
|
|||
<React.Fragment>
|
||||
<CheckmarkIcon
|
||||
color={selected === false ? "transparent" : undefined}
|
||||
/>
|
||||
/>
|
||||
|
||||
</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;"
|
||||
: `
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -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)};
|
||||
`};
|
||||
`;
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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} />
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -14,7 +14,7 @@ type Props = {
|
|||
heading?: React.Node,
|
||||
empty?: React.Node,
|
||||
items: any[],
|
||||
renderItem: any => React.Node,
|
||||
renderItem: (any) => React.Node,
|
||||
};
|
||||
|
||||
@observer
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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}
|
||||
{content}
|
||||
{showCollection &&
|
||||
collection && (
|
||||
<span>
|
||||
in
|
||||
<strong>
|
||||
<Breadcrumb document={document} onlyText />
|
||||
</strong>
|
||||
</span>
|
||||
)}
|
||||
{showCollection && collection && (
|
||||
<span>
|
||||
in
|
||||
<strong>
|
||||
<Breadcrumb document={document} onlyText />
|
||||
</strong>
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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
|
||||
/>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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} /> {collection.name}
|
||||
<CollectionIcon collection={collection} />
|
||||
{collection.name}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -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} /> {collection.name}
|
||||
<CollectionIcon collection={collection} />
|
||||
{collection.name}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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…
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class BaseModel {
|
|||
this.store = store;
|
||||
}
|
||||
|
||||
save = async params => {
|
||||
save = async (params) => {
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -171,14 +171,17 @@ class CollectionScene extends React.Component<Props> {
|
|||
<Centered column>
|
||||
<HelpText>
|
||||
<strong>{collection.name}</strong> doesn’t 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>
|
||||
</Link>
|
||||
|
||||
{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));
|
||||
|
|
|
@ -56,7 +56,7 @@ class CollectionEdit extends React.Component<Props> {
|
|||
}
|
||||
};
|
||||
|
||||
handleDescriptionChange = getValue => {
|
||||
handleDescriptionChange = (getValue) => {
|
||||
this.description = getValue();
|
||||
};
|
||||
|
||||
|
|
|
@ -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> {
|
|||
Can’t find the group you’re 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);
|
||||
|
|
|
@ -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 who’s 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);
|
||||
|
|
|
@ -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)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -39,7 +39,7 @@ const MemberListItem = ({
|
|||
? collectionGroupMembership.permission
|
||||
: undefined
|
||||
}
|
||||
onChange={ev => onUpdate(ev.target.value)}
|
||||
onChange={(ev) => onUpdate(ev.target.value)}
|
||||
labelHidden
|
||||
/>
|
||||
<ButtonWrap>
|
||||
|
|
|
@ -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
|
||||
/>
|
||||
)}
|
||||
|
||||
{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>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -37,9 +37,7 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
|
|||
<Button type="button" onClick={onAdd} icon={<PlusIcon />} neutral>
|
||||
Add
|
||||
</Button>
|
||||
) : (
|
||||
undefined
|
||||
)
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -85,7 +85,7 @@ class CollectionNew extends React.Component<Props> {
|
|||
this.hasOpenedIconPicker = true;
|
||||
};
|
||||
|
||||
handleDescriptionChange = getValue => {
|
||||
handleDescriptionChange = (getValue) => {
|
||||
this.description = getValue();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
You’re 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>
|
||||
You’re 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")`
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
||||
<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`)};
|
||||
`};
|
||||
`;
|
||||
|
||||
|
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 you’d like the option of referencing or restoring this{" "}
|
||||
{document.noun} in the future, consider archiving it instead.
|
||||
</HelpText>
|
||||
)}
|
||||
{!document.isDraft && !document.isArchived && (
|
||||
<HelpText>
|
||||
If you’d 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…" : "I’m sure – Delete"}
|
||||
</Button>
|
||||
|
|
|
@ -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> <a href={share.url} target="_blank">
|
||||
</CopyToClipboard>
|
||||
|
||||
<a href={share.url} target="_blank">
|
||||
Preview
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -10,9 +10,8 @@ const Error404 = () => {
|
|||
<PageTitle title="Not Found" />
|
||||
<h1>Not found</h1>
|
||||
<Empty>
|
||||
We were unable to find the page you’re looking for. Go to the <a href="/">
|
||||
homepage
|
||||
</a>?
|
||||
We were unable to find the page you’re looking for. Go to the
|
||||
<a href="/">homepage</a>?
|
||||
</Empty>
|
||||
</CenteredContent>
|
||||
);
|
||||
|
|
|
@ -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 who’s 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
Reference in New Issue