chore: Update syntax, improve more typing (#1439)

* chore: <React.Fragment> to <>

* flow types
This commit is contained in:
Tom Moor 2020-08-09 09:48:04 -07:00 committed by GitHub
parent ead55442e0
commit e2bd03494d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 239 additions and 221 deletions

View File

@ -40,7 +40,7 @@ class AvatarWithPresence extends React.Component<Props> {
} = this.props;
return (
<React.Fragment>
<>
<Tooltip
tooltip={
<Centered>
@ -69,7 +69,7 @@ class AvatarWithPresence extends React.Component<Props> {
isOpen={this.isOpen}
onRequestClose={this.handleCloseProfile}
/>
</React.Fragment>
</>
);
}
}

View File

@ -33,11 +33,11 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
if (onlyText === true) {
return (
<React.Fragment>
<>
{collection.private && (
<React.Fragment>
<>
<SmallPadlockIcon color="currentColor" size={16} />{" "}
</React.Fragment>
</>
)}
{collection.name}
{path.map((n) => (
@ -46,7 +46,7 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
{n.title}
</React.Fragment>
))}
</React.Fragment>
</>
);
}
@ -59,24 +59,24 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
return (
<Wrapper justify="flex-start" align="center">
{isTemplate && (
<React.Fragment>
<>
<CollectionName to="/templates">
<ShapesIcon color="currentColor" />
&nbsp;
<span>Templates</span>
</CollectionName>
<Slash />
</React.Fragment>
</>
)}
{isDraft && (
<React.Fragment>
<>
<CollectionName to="/drafts">
<EditIcon color="currentColor" />
&nbsp;
<span>Drafts</span>
</CollectionName>
<Slash />
</React.Fragment>
</>
)}
<CollectionName to={collectionUrl(collection.id)}>
<CollectionIcon collection={collection} expanded />
@ -84,17 +84,17 @@ const Breadcrumb = observer(({ document, collections, onlyText }: Props) => {
<span>{collection.name}</span>
</CollectionName>
{isNestedDocument && (
<React.Fragment>
<>
<Slash /> <BreadcrumbMenu label={<Overflow />} path={menuPath} />
</React.Fragment>
</>
)}
{lastPath && (
<React.Fragment>
<>
<Slash />{" "}
<Crumb to={lastPath.url} title={lastPath.title}>
{lastPath.title}
</Crumb>
</React.Fragment>
</>
)}
</Wrapper>
);

View File

@ -155,6 +155,6 @@ function Button({
);
}
export default React.forwardRef((props, ref) => (
export default React.forwardRef<Props, typeof Button>((props, ref) => (
<Button {...props} innerRef={ref} />
));

View File

@ -10,6 +10,7 @@ export type Props = {
labelHidden?: boolean,
className?: string,
note?: string,
short?: boolean,
small?: boolean,
};
@ -42,7 +43,7 @@ export default function Checkbox({
const wrappedLabel = <LabelText small={small}>{label}</LabelText>;
return (
<React.Fragment>
<>
<Wrapper small={small}>
<Label>
<input type="checkbox" {...rest} />
@ -55,6 +56,6 @@ export default function Checkbox({
</Label>
{note && <HelpText small>{note}</HelpText>}
</Wrapper>
</React.Fragment>
</>
);
}

View File

@ -18,10 +18,10 @@ function DocumentMeta({ views, isDraft, document }: Props) {
return (
<Meta document={document}>
{totalViews && !isDraft ? (
<React.Fragment>
<>
&nbsp;&middot; Viewed{" "}
{totalViews === 1 ? "once" : `${totalViews} times`}
</React.Fragment>
</>
) : null}
</Meta>
);

View File

@ -161,7 +161,7 @@ class DropdownMenu extends React.Component<Props> {
closeOnEsc
>
{({ closePortal, openPortal, isOpen, portal }) => (
<React.Fragment>
<>
<Label
onMouseMove={hover ? this.clearCloseTimeout : undefined}
onMouseOut={
@ -220,7 +220,7 @@ class DropdownMenu extends React.Component<Props> {
</Menu>
</Position>
)}
</React.Fragment>
</>
)}
</PortalWithState>
</div>

View File

@ -26,12 +26,12 @@ const DropdownMenuItem = ({
{...rest}
>
{selected !== undefined && (
<React.Fragment>
<>
<CheckmarkIcon
color={selected === false ? "transparent" : undefined}
/>
&nbsp;
</React.Fragment>
</>
)}
{children}
</MenuItem>

View File

@ -15,18 +15,21 @@ import { uploadFile } from "utils/uploadFile";
const EMPTY_ARRAY = [];
type Props = {
id: string,
id?: string,
defaultValue?: string,
readOnly?: boolean,
grow?: boolean,
disableEmbeds?: boolean,
history: RouterHistory,
ui?: UiStore,
};
type PropsWithRef = Props & {
forwardedRef: React.Ref<RichMarkdownEditor>,
ui: UiStore,
history: RouterHistory,
};
@observer
class Editor extends React.Component<Props> {
class Editor extends React.Component<PropsWithRef> {
@observable redirectTo: ?string;
onUploadImage = async (file: File) => {
@ -62,7 +65,9 @@ class Editor extends React.Component<Props> {
};
onShowToast = (message: string) => {
this.props.ui.showToast(message);
if (this.props.ui) {
this.props.ui.showToast(message);
}
};
render() {
@ -120,6 +125,6 @@ const Span = styled.span`
const EditorWithRouterAndTheme = withRouter(withTheme(Editor));
export default React.forwardRef((props, ref) => (
export default React.forwardRef<Props, typeof Editor>((props, ref) => (
<EditorWithRouterAndTheme {...props} forwardedRef={ref} />
));

View File

@ -46,15 +46,15 @@ class GroupListItem extends React.Component<Props> {
const overflow = memberCount - users.length;
return (
<React.Fragment>
<>
<ListItem
title={
<Title onClick={this.handleMembersModalOpen}>{group.name}</Title>
}
subtitle={
<React.Fragment>
<>
{memberCount} member{memberCount === 1 ? "" : "s"}
</React.Fragment>
</>
}
actions={
<Flex align="center">
@ -79,7 +79,7 @@ class GroupListItem extends React.Component<Props> {
>
<GroupMembers group={group} onSubmit={this.handleMembersModalClose} />
</Modal>
</React.Fragment>
</>
);
}
}

View File

@ -31,7 +31,7 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
const [isVisible, setVisible] = React.useState(false);
const timerClose = React.useRef();
const timerOpen = React.useRef();
const cardRef = React.useRef();
const cardRef = React.useRef<?HTMLDivElement>();
const startCloseTimer = () => {
stopOpenTimer();
@ -68,6 +68,8 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
if (cardRef.current) {
cardRef.current.addEventListener("mouseenter", stopCloseTimer);
}
if (cardRef.current) {
cardRef.current.addEventListener("mouseleave", startCloseTimer);
}
@ -82,6 +84,8 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
if (cardRef.current) {
cardRef.current.removeEventListener("mouseenter", stopCloseTimer);
}
if (cardRef.current) {
cardRef.current.removeEventListener("mouseleave", startCloseTimer);
}

View File

@ -48,7 +48,7 @@ class InputRich extends React.Component<Props> {
const Editor = this.editorComponent;
return (
<React.Fragment>
<>
<LabelText>{label}</LabelText>
<StyledOutline
@ -67,7 +67,7 @@ class InputRich extends React.Component<Props> {
"Loading…"
)}
</StyledOutline>
</React.Fragment>
</>
);
}
}

View File

@ -64,7 +64,7 @@ const Modal = ({
if (!isOpen) return null;
return (
<React.Fragment>
<>
<GlobalStyles />
<StyledModal
contentLabel={title}
@ -85,7 +85,7 @@ const Modal = ({
<CloseIcon size={32} color="currentColor" />
</Close>
</StyledModal>
</React.Fragment>
</>
);
};

View File

@ -20,6 +20,6 @@ const Button = styled.button`
}
`;
export default React.forwardRef((props, ref) => (
export default React.forwardRef<any, typeof Button>((props, ref) => (
<Button {...props} ref={ref} />
));

View File

@ -106,10 +106,10 @@ class PaginatedList extends React.Component<Props> {
(this.isLoaded || this.isInitiallyLoaded) && !showLoading && !showEmpty;
return (
<React.Fragment>
<>
{showEmpty && empty}
{showList && (
<React.Fragment>
<>
{heading}
<ArrowKeyNavigation
mode={ArrowKeyNavigation.mode.VERTICAL}
@ -120,10 +120,10 @@ class PaginatedList extends React.Component<Props> {
{this.allowLoadMore && (
<Waypoint key={this.renderCount} onEnter={this.loadMoreResults} />
)}
</React.Fragment>
</>
)}
{showLoading && <ListPlaceholder count={5} />}
</React.Fragment>
</>
);
}
}

View File

@ -55,7 +55,7 @@ class Collections extends React.Component<Props> {
const { collections, ui, documents } = this.props;
const content = (
<React.Fragment>
<>
{collections.orderedData.map((collection) => (
<CollectionLink
key={collection.id}
@ -73,7 +73,7 @@ class Collections extends React.Component<Props> {
label="New collection…"
exact
/>
</React.Fragment>
</>
);
return (

View File

@ -30,7 +30,7 @@ export default function Version() {
<SidebarLink
href="https://github.com/outline/outline/releases"
label={
<React.Fragment>
<>
v{version}
<br />
<LilBadge>
@ -40,7 +40,7 @@ export default function Version() {
releasesBehind === 1 ? "" : "s"
} behind`}
</LilBadge>
</React.Fragment>
</>
}
/>
);

View File

@ -14,10 +14,10 @@ type Props = {
function Theme({ children, ui }: Props) {
return (
<ThemeProvider theme={ui.resolvedTheme === "dark" ? dark : light}>
<React.Fragment>
<>
<GlobalStyles />
{children}
</React.Fragment>
</>
</ThemeProvider>
);
}

View File

@ -24,9 +24,9 @@ class Tooltip extends React.Component<Props> {
if (shortcut) {
content = (
<React.Fragment>
<>
{tooltip} &middot; <Shortcut>{shortcut}</Shortcut>
</React.Fragment>
</>
);
}

View File

@ -7,13 +7,16 @@ import styled from "styled-components";
type Props = {
src?: string,
border?: boolean,
forwardedRef: *,
width?: string,
height?: string,
};
type PropsWithRef = Props & {
forwardedRef: React.Ref<typeof StyledIframe>,
};
@observer
class Frame extends React.Component<Props> {
class Frame extends React.Component<PropsWithRef> {
mounted: boolean;
@observable isLoaded: boolean = false;
@ -79,6 +82,6 @@ const StyledIframe = styled(Iframe)`
border-radius: 3px;
`;
export default React.forwardRef((props, ref) => (
export default React.forwardRef<Props, typeof Frame>((props, ref) => (
<Frame {...props} forwardedRef={ref} />
));

View File

@ -21,23 +21,23 @@ const element = document.getElementById("root");
if (element) {
render(
<React.Fragment>
<>
<ErrorBoundary>
<Provider {...stores}>
<Theme>
<Router>
<React.Fragment>
<>
<ScrollToTop>
<Routes />
</ScrollToTop>
<Toasts />
</React.Fragment>
</>
</Router>
</Theme>
</Provider>
</ErrorBoundary>
{DevTools && <DevTools position={{ bottom: 0, right: 0 }} />}
</React.Fragment>,
</>,
element
);
}

View File

@ -45,7 +45,7 @@ class AccountMenu extends React.Component<Props> {
const { ui } = this.props;
return (
<React.Fragment>
<>
<Modal
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
@ -118,7 +118,7 @@ class AccountMenu extends React.Component<Props> {
Log out
</DropdownMenuItem>
</DropdownMenu>
</React.Fragment>
</>
);
}
}

View File

@ -93,7 +93,7 @@ class CollectionMenu extends React.Component<Props> {
const can = policies.abilities(collection.id);
return (
<React.Fragment>
<>
<VisuallyHidden>
<input
type="file"
@ -117,7 +117,7 @@ class CollectionMenu extends React.Component<Props> {
</Modal>
<DropdownMenu onOpen={onOpen} onClose={onClose} position={position}>
{collection && (
<React.Fragment>
<>
{can.update && (
<DropdownMenuItem onClick={this.onNewDocument}>
New document
@ -142,13 +142,13 @@ class CollectionMenu extends React.Component<Props> {
Export
</DropdownMenuItem>
)}
</React.Fragment>
</>
)}
{can.delete && (
<DropdownMenuItem onClick={this.onDelete}>Delete</DropdownMenuItem>
)}
</DropdownMenu>
</React.Fragment>
</>
);
}
}

View File

@ -153,7 +153,7 @@ class DocumentMenu extends React.Component<Props> {
const canViewHistory = can.read && !can.restore;
return (
<React.Fragment>
<>
<DropdownMenu
className={className}
position={position}
@ -197,7 +197,7 @@ class DocumentMenu extends React.Component<Props> {
</DropdownMenuItem>
)}
{showToggleEmbeds && (
<React.Fragment>
<>
{document.embedsDisabled ? (
<DropdownMenuItem onClick={document.enableEmbeds}>
Enable embeds
@ -207,7 +207,7 @@ class DocumentMenu extends React.Component<Props> {
Disable embeds
</DropdownMenuItem>
)}
</React.Fragment>
</>
)}
{!can.restore && <hr />}
@ -247,11 +247,11 @@ class DocumentMenu extends React.Component<Props> {
)}
<hr />
{canViewHistory && (
<React.Fragment>
<>
<DropdownMenuItem onClick={this.handleDocumentHistory}>
History
</DropdownMenuItem>
</React.Fragment>
</>
)}
{can.download && (
<DropdownMenuItem onClick={this.handleExport}>
@ -282,7 +282,7 @@ class DocumentMenu extends React.Component<Props> {
onSubmit={this.handleCloseTemplateModal}
/>
</Modal>
</React.Fragment>
</>
);
}
}

View File

@ -50,7 +50,7 @@ class GroupMenu extends React.Component<Props> {
const can = policies.abilities(group.id);
return (
<React.Fragment>
<>
<Modal
title="Edit group"
onRequestClose={this.handleEditModalClose}
@ -75,7 +75,7 @@ class GroupMenu extends React.Component<Props> {
<DropdownMenu onOpen={onOpen} onClose={onClose}>
{group && (
<React.Fragment>
<>
<DropdownMenuItem onClick={this.props.onMembers}>
Members
</DropdownMenuItem>
@ -91,10 +91,10 @@ class GroupMenu extends React.Component<Props> {
Delete
</DropdownMenuItem>
)}
</React.Fragment>
</>
)}
</DropdownMenu>
</React.Fragment>
</>
);
}
}

View File

@ -11,7 +11,7 @@ export default class BaseModel {
this.store = store;
}
save = async (params) => {
save = async (params: ?Object) => {
this.isSaving = true;
try {
@ -27,7 +27,7 @@ export default class BaseModel {
}
};
fetch = (options: *) => {
fetch = (options?: any) => {
return this.store.fetch(this.id, options);
};
@ -44,7 +44,7 @@ export default class BaseModel {
}
};
toJS = () => {
toJS = (): Object => {
return { ...this };
};
}

View File

@ -121,7 +121,7 @@ class CollectionScene extends React.Component<Props> {
return (
<Actions align="center" justify="flex-end">
{can.update && (
<React.Fragment>
<>
<Action>
<InputSearch
placeholder="Search in collection…"
@ -141,7 +141,7 @@ class CollectionScene extends React.Component<Props> {
</Tooltip>
</Action>
<Separator />
</React.Fragment>
</>
)}
<Action>
<CollectionMenu collection={this.collection} />
@ -165,7 +165,7 @@ class CollectionScene extends React.Component<Props> {
return (
<CenteredContent>
{collection ? (
<React.Fragment>
<>
<PageTitle title={collection.name} />
{collection.isEmpty ? (
<Centered column>
@ -211,7 +211,7 @@ class CollectionScene extends React.Component<Props> {
</Modal>
</Centered>
) : (
<React.Fragment>
<>
<Heading>
<CollectionIcon collection={collection} size={40} expanded />{" "}
{collection.name}
@ -228,12 +228,12 @@ class CollectionScene extends React.Component<Props> {
)}
{hasPinnedDocuments && (
<React.Fragment>
<>
<Subheading>
<TinyPinIcon size={18} /> Pinned
</Subheading>
<DocumentList documents={pinnedDocuments} showPin />
</React.Fragment>
</>
)}
<Tabs>
@ -296,18 +296,18 @@ class CollectionScene extends React.Component<Props> {
/>
</Route>
</Switch>
</React.Fragment>
</>
)}
{this.renderActions()}
</React.Fragment>
</>
) : (
<React.Fragment>
<>
<Heading>
<Mask height={35} />
</Heading>
<ListPlaceholder count={5} />
</React.Fragment>
</>
)}
</CenteredContent>
);

View File

@ -125,7 +125,7 @@ class CollectionMembers extends React.Component<Props> {
return (
<Flex column>
{collection.private ? (
<React.Fragment>
<>
<HelpText>
Choose which groups and team members have access to view and edit
documents in the private <strong>{collection.name}</strong>{" "}
@ -146,7 +146,7 @@ class CollectionMembers extends React.Component<Props> {
Add groups
</Button>
</span>
</React.Fragment>
</>
) : (
<HelpText>
The <strong>{collection.name}</strong> collection is accessible by
@ -195,7 +195,7 @@ class CollectionMembers extends React.Component<Props> {
</GroupsWrap>
)}
{collection.private ? (
<React.Fragment>
<>
<span>
<Button
type="button"
@ -208,7 +208,7 @@ class CollectionMembers extends React.Component<Props> {
</span>
<Subheading>Individual Members</Subheading>
</React.Fragment>
</>
) : (
<Subheading>Members</Subheading>
)}

View File

@ -30,7 +30,7 @@ const MemberListItem = ({
onRemove={onRemove}
onUpdate={onUpdate}
renderActions={({ openMembersModal }) => (
<React.Fragment>
<>
<Select
label="Permissions"
options={PERMISSIONS}
@ -51,7 +51,7 @@ const MemberListItem = ({
<DropdownMenuItem onClick={onRemove}>Remove</DropdownMenuItem>
</DropdownMenu>
</ButtonWrap>
</React.Fragment>
</>
)}
/>
);

View File

@ -37,17 +37,17 @@ const MemberListItem = ({
<ListItem
title={user.name}
subtitle={
<React.Fragment>
<>
{user.lastActiveAt ? (
<React.Fragment>
<>
Active <Time dateTime={user.lastActiveAt} /> ago
</React.Fragment>
</>
) : (
"Never signed in"
)}
{!user.lastActiveAt && <Badge>Invited</Badge>}
{user.isAdmin && <Badge primary={user.isAdmin}>Admin</Badge>}
</React.Fragment>
</>
}
image={<Avatar src={user.avatarUrl} size={40} />}
actions={

View File

@ -20,17 +20,17 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
title={user.name}
image={<Avatar src={user.avatarUrl} size={40} />}
subtitle={
<React.Fragment>
<>
{user.lastActiveAt ? (
<React.Fragment>
<>
Active <Time dateTime={user.lastActiveAt} /> ago
</React.Fragment>
</>
) : (
"Never signed in"
)}
{!user.lastActiveAt && <Badge>Invited</Badge>}
{user.isAdmin && <Badge primary={user.isAdmin}>Admin</Badge>}
</React.Fragment>
</>
}
actions={
canEdit ? (

View File

@ -3,7 +3,7 @@ import invariant from "invariant";
import { observable } from "mobx";
import { observer, inject } from "mobx-react";
import * as React from "react";
import type { Location, RouterHistory, Match } from "react-router-dom";
import type { RouterHistory, Match } from "react-router-dom";
import { withRouter } from "react-router-dom";
import DocumentsStore from "stores/DocumentsStore";
import PoliciesStore from "stores/PoliciesStore";
@ -18,12 +18,13 @@ import DocumentComponent from "./Document";
import HideSidebar from "./HideSidebar";
import Loading from "./Loading";
import SocketPresence from "./SocketPresence";
import { type LocationWithState } from "types";
import { NotFoundError, OfflineError } from "utils/errors";
import { matchDocumentEdit, updateDocumentUrl } from "utils/routeHelpers";
type Props = {|
match: Match,
location: Location,
location: LocationWithState,
shares: SharesStore,
documents: DocumentsStore,
policies: PoliciesStore,
@ -166,10 +167,10 @@ class DataLoader extends React.Component<Props> {
if (!document) {
return (
<React.Fragment>
<>
<Loading location={location} />
{this.isEditing && <HideSidebar ui={ui} />}
</React.Fragment>
</>
);
}

View File

@ -375,7 +375,7 @@ class DocumentScene extends React.Component<Props> {
<Container justify="center" column auto>
{!readOnly && (
<React.Fragment>
<>
<Prompt
when={this.isDirty && !this.isUploading}
message={DISCARD_CHANGES}
@ -384,7 +384,7 @@ class DocumentScene extends React.Component<Props> {
when={this.isUploading && !this.isDirty}
message={UPLOADING_WARNING}
/>
</React.Fragment>
</>
)}
{!isShare && (
<Header
@ -427,12 +427,12 @@ class DocumentScene extends React.Component<Props> {
Deleted by {document.updatedBy.name}{" "}
<Time dateTime={document.deletedAt} /> ago
{document.permanentlyDeletedAt && (
<React.Fragment>
<>
<br />
This {document.noun} will be permanently deleted in{" "}
<Time dateTime={document.permanentlyDeletedAt} /> unless
restored.
</React.Fragment>
</>
)}
</Notice>
)}
@ -473,12 +473,12 @@ class DocumentScene extends React.Component<Props> {
/>
</Flex>
{readOnly && !isShare && !revision && (
<React.Fragment>
<>
<MarkAsViewed document={document} />
<ReferencesWrapper isOnlyTitle={document.isOnlyTitle}>
<References document={document} />
</ReferencesWrapper>
</React.Fragment>
</>
)}
</MaxWidth>
</Container>

View File

@ -25,23 +25,23 @@ type Props = {
@observer
class DocumentEditor extends React.Component<Props> {
@observable activeLinkEvent: ?MouseEvent;
editor: ?Editor;
editor = React.createRef<typeof Editor>();
focusAtStart = () => {
if (this.editor) {
this.editor.focusAtStart();
if (this.editor.current) {
this.editor.current.focusAtStart();
}
};
focusAtEnd = () => {
if (this.editor) {
this.editor.focusAtEnd();
if (this.editor.current) {
this.editor.current.focusAtEnd();
}
};
getHeadings = () => {
if (this.editor) {
return this.editor.getHeadings();
if (this.editor.current) {
return this.editor.current.getHeadings();
}
return [];
@ -89,7 +89,7 @@ class DocumentEditor extends React.Component<Props> {
/>
<DocumentMeta isDraft={isDraft} document={document} />
<Editor
ref={(ref) => (this.editor = ref)}
ref={this.editor}
autoFocus={title && !this.props.defaultValue}
placeholder="…the rest is up to you"
onHoverLink={this.handleLinkActive}

View File

@ -162,7 +162,7 @@ class Header extends React.Component<Props> {
<BreadcrumbAndContents align="center" justify="flex-start">
<Breadcrumb document={document} />
{!isEditing && (
<React.Fragment>
<>
<Slash />
<Tooltip
tooltip={ui.tocVisible ? "Hide contents" : "Show contents"}
@ -183,7 +183,7 @@ class Header extends React.Component<Props> {
small
/>
</Tooltip>
</React.Fragment>
</>
)}
</BreadcrumbAndContents>
{this.isScrolled && (
@ -216,10 +216,10 @@ class Header extends React.Component<Props> {
<Tooltip
tooltip={
isPubliclyShared ? (
<React.Fragment>
<>
Anyone with the link <br />
can view this document
</React.Fragment>
</>
) : (
""
)
@ -239,7 +239,7 @@ class Header extends React.Component<Props> {
</Action>
)}
{isEditing && (
<React.Fragment>
<>
<Action>
<Tooltip
tooltip="Save"
@ -258,7 +258,7 @@ class Header extends React.Component<Props> {
</Button>
</Tooltip>
</Action>
</React.Fragment>
</>
)}
{canEdit && (
<Action>
@ -330,7 +330,7 @@ class Header extends React.Component<Props> {
</Action>
)}
{!isEditing && (
<React.Fragment>
<>
<Separator />
<Action>
<DocumentMenu
@ -340,7 +340,7 @@ class Header extends React.Component<Props> {
showPrint
/>
</Action>
</React.Fragment>
</>
)}
</Wrapper>
</Actions>

View File

@ -26,7 +26,7 @@ class KeyboardShortcutsButton extends React.Component<Props> {
render() {
return (
<React.Fragment>
<>
<Modal
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
@ -44,7 +44,7 @@ class KeyboardShortcutsButton extends React.Component<Props> {
<KeyboardIcon />
</Button>
</Tooltip>
</React.Fragment>
</>
);
}
}

View File

@ -1,13 +1,13 @@
// @flow
import * as React from "react";
import type { Location } from "react-router-dom";
import CenteredContent from "components/CenteredContent";
import LoadingPlaceholder from "components/LoadingPlaceholder";
import PageTitle from "components/PageTitle";
import Container from "./Container";
import type { LocationWithState } from "types";
type Props = {|
location: Location,
location: LocationWithState,
|};
export default function Loading({ location }: Props) {

View File

@ -80,7 +80,7 @@ class DocumentShare extends React.Component<Props> {
.
</HelpText>
{canPublish && (
<React.Fragment>
<>
<Switch
id="published"
label="Publish to internet"
@ -96,7 +96,7 @@ class DocumentShare extends React.Component<Props> {
: "Only team members with access can view this document"}
</PrivacyText>
</Privacy>
</React.Fragment>
</>
)}
<br />
<Input

View File

@ -62,7 +62,7 @@ class GroupMembers extends React.Component<Props> {
return (
<Flex column>
{can.update ? (
<React.Fragment>
<>
<HelpText>
Add and remove team members in the <strong>{group.name}</strong>{" "}
group. Adding people to the group will give them access to any
@ -78,7 +78,7 @@ class GroupMembers extends React.Component<Props> {
Add people
</Button>
</span>
</React.Fragment>
</>
) : (
<HelpText>
Listing team members in the <strong>{group.name}</strong> group.

View File

@ -27,17 +27,17 @@ const GroupMemberListItem = ({
<ListItem
title={user.name}
subtitle={
<React.Fragment>
<>
{user.lastActiveAt ? (
<React.Fragment>
<>
Active <Time dateTime={user.lastActiveAt} /> ago
</React.Fragment>
</>
) : (
"Never signed in"
)}
{!user.lastActiveAt && <Badge>Invited</Badge>}
{user.isAdmin && <Badge primary={user.isAdmin}>Admin</Badge>}
</React.Fragment>
</>
}
image={<Avatar src={user.avatarUrl} size={40} />}
actions={

View File

@ -20,17 +20,17 @@ const UserListItem = ({ user, onAdd, canEdit }: Props) => {
title={user.name}
image={<Avatar src={user.avatarUrl} size={32} />}
subtitle={
<React.Fragment>
<>
{user.lastActiveAt ? (
<React.Fragment>
<>
Active <Time dateTime={user.lastActiveAt} /> ago
</React.Fragment>
</>
) : (
"Never signed in"
)}
{!user.lastActiveAt && <Badge>Invited</Badge>}
{user.isAdmin && <Badge primary={user.isAdmin}>Admin</Badge>}
</React.Fragment>
</>
}
actions={
canEdit ? (

View File

@ -51,7 +51,7 @@ class GroupNew extends React.Component<Props> {
render() {
return (
<React.Fragment>
<>
<form onSubmit={this.handleSubmit}>
<HelpText>
Groups are for organizing your team. They work best when centered
@ -82,7 +82,7 @@ class GroupNew extends React.Component<Props> {
>
<GroupMembers group={this.group} />
</Modal>
</React.Fragment>
</>
);
}
}

View File

@ -111,10 +111,10 @@ class Invite extends React.Component<Props> {
Invite team members to join your knowledge base. They will need to
sign in with {team.signinMethods}.{" "}
{can.update && (
<React.Fragment>
<>
As an admin you can also{" "}
<Link to="/settings/security">enable email sign-in</Link>.
</React.Fragment>
</>
)}
</HelpText>
)}

View File

@ -8,7 +8,7 @@ type Props = {
export default function Notices({ notice }: Props) {
return (
<React.Fragment>
<>
{notice === "google-hd" && (
<NoticeAlert>
Sorry, Google sign in cannot be used with a personal email. Please try
@ -51,6 +51,6 @@ export default function Notices({ notice }: Props) {
please contact a team admin.
</NoticeAlert>
)}
</React.Fragment>
</>
);
}

View File

@ -72,7 +72,7 @@ class Service extends React.Component<Props, State> {
onSubmit={this.handleSubmitEmail}
>
{this.state.showEmailSignin ? (
<React.Fragment>
<>
<InputLarge
type="email"
name="email"
@ -87,7 +87,7 @@ class Service extends React.Component<Props, State> {
<ButtonLarge type="submit" disabled={this.state.isSubmitting}>
Sign In
</ButtonLarge>
</React.Fragment>
</>
) : (
<ButtonLarge type="submit" icon={<EmailIcon />} fullwidth>
Continue with Email

View File

@ -125,12 +125,12 @@ class Login extends React.Component<Props, State> {
{...defaultService}
/>
{hasMultipleServices && (
<React.Fragment>
<>
<Note>
You signed in with {defaultService.name} last time.
</Note>
<Or />
</React.Fragment>
</>
)}
</React.Fragment>
)}

View File

@ -46,7 +46,7 @@ type Props = {
@observer
class Search extends React.Component<Props> {
firstDocument: ?DocumentPreview;
firstDocument: ?typeof DocumentPreview;
@observable
query: string = decodeURIComponent(this.props.match.params.term || "");

View File

@ -117,7 +117,7 @@ class Details extends React.Component<Props> {
short
/>
{env.SUBDOMAINS_ENABLED && (
<React.Fragment>
<>
<Input
label="Subdomain"
name="subdomain"
@ -134,7 +134,7 @@ class Details extends React.Component<Props> {
<strong>{this.subdomain}.getoutline.com</strong>
</HelpText>
)}
</React.Fragment>
</>
)}
<Button type="submit" disabled={isSaving || !this.isValid}>
{isSaving ? "Saving…" : "Save"}

View File

@ -84,14 +84,14 @@ class Events extends React.Component<Props> {
{showLoading ? (
<ListPlaceholder count={5} />
) : (
<React.Fragment>
<>
{events.orderedData.map((event) => (
<EventListItem event={event} />
))}
{this.allowLoadMore && (
<Waypoint key={this.offset} onEnter={this.loadMoreResults} />
)}
</React.Fragment>
</>
)}
</List>
</CenteredContent>

View File

@ -104,12 +104,12 @@ class People extends React.Component<Props> {
</Tab>
{can.invite && (
<React.Fragment>
<>
<Separator />
<Tab to="/settings/people/invited" exact>
Invited
</Tab>
</React.Fragment>
</>
)}
</Tabs>
<PaginatedList

View File

@ -16,121 +16,119 @@ const description = (event) => {
switch (event.name) {
case "api_keys.create":
return (
<React.Fragment>
<>
Created the API token <strong>{event.data.name}</strong>
</React.Fragment>
</>
);
case "api_keys.delete":
return (
<React.Fragment>
<>
Revoked the API token <strong>{event.data.name}</strong>
</React.Fragment>
</>
);
case "teams.create":
return "Created the team";
case "shares.create":
case "shares.revoke":
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} a{" "}
<Link to={`/share/${event.modelId || ""}`}>share link</Link> to the{" "}
<Link to={`/doc/${event.documentId}`}>{event.data.name}</Link>{" "}
document
</React.Fragment>
</>
);
case "shares.update":
return (
<React.Fragment>
<>
{event.data.published ? (
<React.Fragment>
<>
Published a document{" "}
<Link to={`/share/${event.modelId || ""}`}>share link</Link>
</React.Fragment>
</>
) : (
<React.Fragment>
<>
Unpublished a document{" "}
<Link to={`/share/${event.modelId || ""}`}>share link</Link>
</React.Fragment>
</>
)}
</React.Fragment>
</>
);
case "users.create":
return (
<React.Fragment>{event.data.name} created an account</React.Fragment>
);
return <>{event.data.name} created an account</>;
case "users.invite":
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} {event.data.name} (
<a href={`mailto:${event.data.email || ""}`}>
{event.data.email || ""}
</a>
)
</React.Fragment>
</>
);
case "users.suspend":
return (
<React.Fragment>
<>
Suspended <strong>{event.data.name}s</strong> account
</React.Fragment>
</>
);
case "users.activate":
return (
<React.Fragment>
<>
Unsuspended <strong>{event.data.name}s</strong> account
</React.Fragment>
</>
);
case "users.promote":
return (
<React.Fragment>
<>
Made <strong>{event.data.name}</strong> an admin
</React.Fragment>
</>
);
case "users.demote":
return (
<React.Fragment>
<>
Made <strong>{event.data.name}</strong> a member
</React.Fragment>
</>
);
case "users.delete":
return "Deleted their account";
case "groups.create":
return (
<React.Fragment>
<>
Created the group <strong>{event.data.name}</strong>
</React.Fragment>
</>
);
case "groups.update":
return (
<React.Fragment>
<>
Update the group <strong>{event.data.name}</strong>
</React.Fragment>
</>
);
case "groups.delete":
return (
<React.Fragment>
<>
Deleted the group <strong>{event.data.name}</strong>
</React.Fragment>
</>
);
case "collections.add_user":
case "collections.add_group":
return (
<React.Fragment>
<>
Granted <strong>{event.data.name}</strong> access to a{" "}
<Link to={`/collections/${event.collectionId || ""}`}>
collection
</Link>
</React.Fragment>
</>
);
case "collections.remove_user":
case "collections.remove_group":
return (
<React.Fragment>
<>
Revoked <strong>{event.data.name}</strong> access to a{" "}
<Link to={`/collections/${event.collectionId || ""}`}>
collection
</Link>
</React.Fragment>
</>
);
default:
}
@ -138,60 +136,60 @@ const description = (event) => {
if (event.documentId) {
if (event.name === "documents.delete") {
return (
<React.Fragment>
<>
Deleted the <strong>{event.data.title}</strong> document
</React.Fragment>
</>
);
}
if (event.name === "documents.create") {
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} the{" "}
<Link to={`/doc/${event.documentId}`}>
{event.data.title || "Untitled"}
</Link>{" "}
document{" "}
{event.data.templateId && (
<React.Fragment>
<>
from a <Link to={`/doc/${event.data.templateId}`}>template</Link>
</React.Fragment>
</>
)}
</React.Fragment>
</>
);
}
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} the{" "}
<Link to={`/doc/${event.documentId}`}>
{event.data.title || "Untitled"}
</Link>{" "}
document
</React.Fragment>
</>
);
}
if (event.collectionId) {
if (event.name === "collections.delete") {
return (
<React.Fragment>
<>
Deleted the <strong>{event.data.name}</strong> collection
</React.Fragment>
</>
);
}
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} the{" "}
<Link to={`/collections/${event.collectionId || ""}`}>
{event.data.name}
</Link>{" "}
collection
</React.Fragment>
</>
);
}
if (event.userId) {
return (
<React.Fragment>
<>
{capitalize(event.verbPastTense)} the user {event.data.name}
</React.Fragment>
</>
);
}
return "";
@ -204,10 +202,10 @@ const EventListItem = ({ event }: Props) => {
title={event.actor.name}
image={<Avatar src={event.actor.avatarUrl} size={32} />}
subtitle={
<React.Fragment>
<>
{description(event)} <Time dateTime={event.createdAt} /> ago &middot;{" "}
<strong>{event.name}</strong>
</React.Fragment>
</>
}
actions={
event.actorIpAddress ? (

View File

@ -16,7 +16,6 @@ const NotificationListItem = ({
setting,
title,
event,
enabled,
onChange,
disabled,
description,

View File

@ -15,10 +15,10 @@ const ShareListItem = ({ share }: Props) => {
key={share.id}
title={share.documentTitle}
subtitle={
<React.Fragment>
<>
Shared <Time dateTime={share.createdAt} /> ago by{" "}
{share.createdBy.name}
</React.Fragment>
</>
}
actions={<ShareMenu share={share} />}
/>

View File

@ -6,7 +6,7 @@ import ListItem from "components/List/Item";
type Props = {
token: ApiKey,
onDelete: (tokenId: string) => void,
onDelete: (tokenId: string) => Promise<void>,
};
const TokenListItem = ({ token, onDelete }: Props) => {

View File

@ -35,7 +35,7 @@ class UserListItem extends React.Component<Props> {
<ListItem
title={<Title onClick={this.handleOpenProfile}>{user.name}</Title>}
image={
<React.Fragment>
<>
<Avatar
src={user.avatarUrl}
size={40}
@ -46,21 +46,21 @@ class UserListItem extends React.Component<Props> {
isOpen={this.profileOpen}
onRequestClose={this.handleCloseProfile}
/>
</React.Fragment>
</>
}
subtitle={
<React.Fragment>
<>
{user.email ? `${user.email} · ` : undefined}
{user.lastActiveAt ? (
<React.Fragment>
<>
Active <Time dateTime={user.lastActiveAt} /> ago
</React.Fragment>
</>
) : (
"Invited"
)}
{user.isAdmin && <Badge primary={user.isAdmin}>Admin</Badge>}
{user.isSuspended && <Badge>Suspended</Badge>}
</React.Fragment>
</>
}
actions={showMenu ? <UserMenu user={user} /> : undefined}
/>

View File

@ -1,6 +1,13 @@
// @flow
import { type Location } from "react-router-dom";
import Document from "models/Document";
export type LocationWithState = Location & {
state: {
[key: string]: string,
},
};
export type Toast = {
id: string,
createdAt: string,