refactor: ♻️ refactor isHosted && type clean up (#3290)

* refactor: ♻️ refactor isHosted && type clean up

Change-Id: I4dfbad8a07607432801de78920ce42bf81e46498

* refactor: ♻️ code clean up

Change-Id: I8f487a33d332a2acaff84397a97371b56ace28a1

* feat: 💄 lint

Change-Id: I776b1a5e249bdb542f8e6da7cb2277821cf91094

* feat:  ci type

Change-Id: I486dde7bf60321238e9a394c40ad8cdb8bfc54c8

* feat: some code sugession

Change-Id: I4761d057344b95a98e99068d312a42292977875b
This commit is contained in:
忽如寄
2022-03-28 06:18:37 +08:00
committed by GitHub
parent f7b1f3ad6d
commit 9f400af73b
58 changed files with 131 additions and 161 deletions

View File

@@ -101,9 +101,7 @@ export function actionToKBar(
keywords: action.keywords ?? "", keywords: action.keywords ?? "",
shortcut: action.shortcut || [], shortcut: action.shortcut || [],
icon: resolvedIcon, icon: resolvedIcon,
perform: action.perform perform: action.perform ? () => action?.perform?.(context) : undefined,
? () => action.perform && action.perform(context)
: undefined,
}, },
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
].concat(children.map((child) => ({ ...child, parent: action.id }))); ].concat(children.map((child) => ({ ...child, parent: action.id })));

View File

@@ -15,7 +15,7 @@ type Props = {
const Authenticated = ({ children }: Props) => { const Authenticated = ({ children }: Props) => {
const { auth } = useStores(); const { auth } = useStores();
const { i18n } = useTranslation(); const { i18n } = useTranslation();
const language = auth.user && auth.user.language; const language = auth.user?.language;
// Watching for language changes here as this is the earliest point we have // Watching for language changes here as this is the earliest point we have
// the user available and means we can start loading translations faster // the user available and means we can start loading translations faster

View File

@@ -67,7 +67,7 @@ function CommandBar() {
); );
} }
function KBarPortal({ children }: { children: React.ReactNode }) { const KBarPortal: React.FC = ({ children }) => {
const { showing } = useKBar((state) => ({ const { showing } = useKBar((state) => ({
showing: state.visualState !== "hidden", showing: state.visualState !== "hidden",
})); }));
@@ -77,7 +77,7 @@ function KBarPortal({ children }: { children: React.ReactNode }) {
} }
return <Portal>{children}</Portal>; return <Portal>{children}</Portal>;
} };
const Hint = styled(Text)` const Hint = styled(Text)`
display: flex; display: flex;

View File

@@ -8,7 +8,6 @@ import MenuIconWrapper from "../MenuIconWrapper";
type Props = { type Props = {
onClick?: (arg0: React.SyntheticEvent) => void | Promise<void>; onClick?: (arg0: React.SyntheticEvent) => void | Promise<void>;
children?: React.ReactNode;
selected?: boolean; selected?: boolean;
disabled?: boolean; disabled?: boolean;
dangerous?: boolean; dangerous?: boolean;
@@ -21,7 +20,7 @@ type Props = {
icon?: React.ReactElement; icon?: React.ReactElement;
}; };
const MenuItem = ({ const MenuItem: React.FC<Props> = ({
onClick, onClick,
children, children,
selected, selected,
@@ -30,7 +29,7 @@ const MenuItem = ({
hide, hide,
icon, icon,
...rest ...rest
}: Props) => { }) => {
const handleClick = React.useCallback( const handleClick = React.useCallback(
(ev) => { (ev) => {
if (onClick) { if (onClick) {

View File

@@ -38,19 +38,18 @@ type Props = {
visible?: boolean; visible?: boolean;
placement?: Placement; placement?: Placement;
animating?: boolean; animating?: boolean;
children: React.ReactNode;
unstable_disclosureRef?: React.RefObject<HTMLElement | null>; unstable_disclosureRef?: React.RefObject<HTMLElement | null>;
onOpen?: () => void; onOpen?: () => void;
onClose?: () => void; onClose?: () => void;
hide?: () => void; hide?: () => void;
}; };
export default function ContextMenu({ const ContextMenu: React.FC<Props> = ({
children, children,
onOpen, onOpen,
onClose, onClose,
...rest ...rest
}: Props) { }) => {
const previousVisible = usePrevious(rest.visible); const previousVisible = usePrevious(rest.visible);
const maxHeight = useMenuHeight(rest.visible, rest.unstable_disclosureRef); const maxHeight = useMenuHeight(rest.visible, rest.unstable_disclosureRef);
const backgroundRef = React.useRef<HTMLDivElement>(null); const backgroundRef = React.useRef<HTMLDivElement>(null);
@@ -137,7 +136,9 @@ export default function ContextMenu({
)} )}
</> </>
); );
} };
export default ContextMenu;
export const Backdrop = styled.div` export const Backdrop = styled.div`
animation: ${fadeIn} 200ms ease-in-out; animation: ${fadeIn} 200ms ease-in-out;

View File

@@ -35,11 +35,10 @@ type Props = {
showLastViewed?: boolean; showLastViewed?: boolean;
showParentDocuments?: boolean; showParentDocuments?: boolean;
document: Document; document: Document;
children?: React.ReactNode;
to?: string; to?: string;
}; };
function DocumentMeta({ const DocumentMeta: React.FC<Props> = ({
showPublished, showPublished,
showCollection, showCollection,
showLastViewed, showLastViewed,
@@ -48,7 +47,7 @@ function DocumentMeta({
children, children,
to, to,
...rest ...rest
}: Props) { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { collections } = useStores(); const { collections } = useStores();
const user = useCurrentUser(); const user = useCurrentUser();
@@ -172,6 +171,6 @@ function DocumentMeta({
{children} {children}
</Container> </Container>
); );
} };
export default observer(DocumentMeta); export default observer(DocumentMeta);

View File

@@ -10,6 +10,7 @@ import CenteredContent from "~/components/CenteredContent";
import PageTitle from "~/components/PageTitle"; import PageTitle from "~/components/PageTitle";
import Text from "~/components/Text"; import Text from "~/components/Text";
import env from "~/env"; import env from "~/env";
import isHosted from "~/utils/isHosted";
type Props = WithTranslation & { type Props = WithTranslation & {
reloadOnChunkMissing?: boolean; reloadOnChunkMissing?: boolean;
@@ -61,7 +62,7 @@ class ErrorBoundary extends React.Component<Props> {
if (this.error) { if (this.error) {
const error = this.error; const error = this.error;
const isReported = !!env.SENTRY_DSN && env.DEPLOYMENT === "hosted"; const isReported = !!env.SENTRY_DSN && isHosted;
const isChunkError = this.error.message.match(/chunk/); const isChunkError = this.error.message.match(/chunk/);
if (isChunkError) { if (isChunkError) {

View File

@@ -22,7 +22,6 @@ function eachMinute(fn: () => void) {
type Props = { type Props = {
dateTime: string; dateTime: string;
children?: React.ReactNode;
tooltipDelay?: number; tooltipDelay?: number;
addSuffix?: boolean; addSuffix?: boolean;
shorten?: boolean; shorten?: boolean;
@@ -30,7 +29,7 @@ type Props = {
format?: string; format?: string;
}; };
function LocaleTime({ const LocaleTime: React.FC<Props> = ({
addSuffix, addSuffix,
children, children,
dateTime, dateTime,
@@ -38,7 +37,7 @@ function LocaleTime({
format, format,
relative, relative,
tooltipDelay, tooltipDelay,
}: Props) { }) => {
const userLocale = useUserLocale(); const userLocale = useUserLocale();
const [_, setMinutesMounted] = React.useState(0); // eslint-disable-line @typescript-eslint/no-unused-vars const [_, setMinutesMounted] = React.useState(0); // eslint-disable-line @typescript-eslint/no-unused-vars
const callback = React.useRef<() => void>(); const callback = React.useRef<() => void>();
@@ -86,6 +85,6 @@ function LocaleTime({
<time dateTime={dateTime}>{children || content}</time> <time dateTime={dateTime}>{children || content}</time>
</Tooltip> </Tooltip>
); );
} };
export default LocaleTime; export default LocaleTime;

View File

@@ -4,12 +4,11 @@ import Flex from "./Flex";
import Text from "./Text"; import Text from "./Text";
type Props = { type Props = {
children: React.ReactNode;
icon?: JSX.Element; icon?: JSX.Element;
description?: JSX.Element; description?: JSX.Element;
}; };
const Notice = ({ children, icon, description }: Props) => { const Notice: React.FC<Props> = ({ children, icon, description }) => {
return ( return (
<Container> <Container>
<Flex as="span" gap={8}> <Flex as="span" gap={8}>

View File

@@ -1,11 +1,7 @@
import * as React from "react"; import * as React from "react";
import Notice from "~/components/Notice"; import Notice from "~/components/Notice";
export default function AlertNotice({ const AlertNotice: React.FC = ({ children }) => {
children,
}: {
children: React.ReactNode;
}) {
return ( return (
<Notice> <Notice>
<svg <svg
@@ -28,4 +24,6 @@ export default function AlertNotice({
{children} {children}
</Notice> </Notice>
); );
} };
export default AlertNotice;

View File

@@ -16,7 +16,7 @@ const PageTitle = ({ title, favicon }: Props) => {
return ( return (
<Helmet> <Helmet>
<title> <title>
{team && team.name ? `${title} - ${team.name}` : `${title} - Outline`} {team?.name ? `${title} - ${team.name}` : `${title} - Outline`}
</title> </title>
{favicon ? ( {favicon ? (
<link rel="shortcut icon" href={favicon} /> <link rel="shortcut icon" href={favicon} />

View File

@@ -7,12 +7,11 @@ import useMobile from "~/hooks/useMobile";
import { fadeAndScaleIn } from "~/styles/animations"; import { fadeAndScaleIn } from "~/styles/animations";
type Props = { type Props = {
children: React.ReactNode;
tabIndex?: number; tabIndex?: number;
width?: number; width?: number;
}; };
function Popover({ children, width = 380, ...rest }: Props) { const Popover: React.FC<Props> = ({ children, width = 380, ...rest }) => {
const isMobile = useMobile(); const isMobile = useMobile();
if (isMobile) { if (isMobile) {
@@ -28,7 +27,7 @@ function Popover({ children, width = 380, ...rest }: Props) {
<Contents $width={width}>{children}</Contents> <Contents $width={width}>{children}</Contents>
</ReakitPopover> </ReakitPopover>
); );
} };
const Contents = styled.div<{ $width?: number }>` const Contents = styled.div<{ $width?: number }>`
animation: ${fadeAndScaleIn} 200ms ease; animation: ${fadeAndScaleIn} 200ms ease;

View File

@@ -8,13 +8,12 @@ type Props = {
icon?: React.ReactNode; icon?: React.ReactNode;
title?: React.ReactNode; title?: React.ReactNode;
textTitle?: string; textTitle?: string;
children: React.ReactNode;
breadcrumb?: React.ReactNode; breadcrumb?: React.ReactNode;
actions?: React.ReactNode; actions?: React.ReactNode;
centered?: boolean; centered?: boolean;
}; };
function Scene({ const Scene: React.FC<Props> = ({
title, title,
icon, icon,
textTitle, textTitle,
@@ -22,7 +21,7 @@ function Scene({
breadcrumb, breadcrumb,
children, children,
centered, centered,
}: Props) { }) => {
return ( return (
<FillWidth> <FillWidth>
<PageTitle title={textTitle || title} /> <PageTitle title={textTitle || title} />
@@ -47,7 +46,7 @@ function Scene({
)} )}
</FillWidth> </FillWidth>
); );
} };
const FillWidth = styled.div` const FillWidth = styled.div`
width: 100%; width: 100%;

View File

@@ -25,7 +25,7 @@ import ArchiveLink from "./components/ArchiveLink";
import Collections from "./components/Collections"; import Collections from "./components/Collections";
import Section from "./components/Section"; import Section from "./components/Section";
import SidebarAction from "./components/SidebarAction"; import SidebarAction from "./components/SidebarAction";
import SidebarButton from "./components/SidebarButton"; import SidebarButton, { SidebarButtonProps } from "./components/SidebarButton";
import SidebarLink from "./components/SidebarLink"; import SidebarLink from "./components/SidebarLink";
import Starred from "./components/Starred"; import Starred from "./components/Starred";
import TrashLink from "./components/TrashLink"; import TrashLink from "./components/TrashLink";
@@ -55,7 +55,7 @@ function AppSidebar() {
{dndArea && ( {dndArea && (
<DndProvider backend={HTML5Backend} options={html5Options}> <DndProvider backend={HTML5Backend} options={html5Options}>
<OrganizationMenu> <OrganizationMenu>
{(props) => ( {(props: SidebarButtonProps) => (
<SidebarButton <SidebarButton
{...props} {...props}
title={team.name} title={team.name}

View File

@@ -7,8 +7,8 @@ import { useHistory } from "react-router-dom";
import styled from "styled-components"; import styled from "styled-components";
import Flex from "~/components/Flex"; import Flex from "~/components/Flex";
import Scrollable from "~/components/Scrollable"; import Scrollable from "~/components/Scrollable";
import env from "~/env";
import useAuthorizedSettingsConfig from "~/hooks/useAuthorizedSettingsConfig"; import useAuthorizedSettingsConfig from "~/hooks/useAuthorizedSettingsConfig";
import isHosted from "~/utils/isHosted";
import Sidebar from "./Sidebar"; import Sidebar from "./Sidebar";
import Header from "./components/Header"; import Header from "./components/Header";
import Section from "./components/Section"; import Section from "./components/Section";
@@ -16,8 +16,6 @@ import SidebarButton from "./components/SidebarButton";
import SidebarLink from "./components/SidebarLink"; import SidebarLink from "./components/SidebarLink";
import Version from "./components/Version"; import Version from "./components/Version";
const isHosted = env.DEPLOYMENT === "hosted";
function SettingsSidebar() { function SettingsSidebar() {
const { t } = useTranslation(); const { t } = useTranslation();
const history = useHistory(); const history = useHistory();

View File

@@ -13,7 +13,7 @@ import AccountMenu from "~/menus/AccountMenu";
import { fadeIn } from "~/styles/animations"; import { fadeIn } from "~/styles/animations";
import Avatar from "../Avatar"; import Avatar from "../Avatar";
import ResizeBorder from "./components/ResizeBorder"; import ResizeBorder from "./components/ResizeBorder";
import SidebarButton from "./components/SidebarButton"; import SidebarButton, { SidebarButtonProps } from "./components/SidebarButton";
import Toggle, { ToggleButton, Positioner } from "./components/Toggle"; import Toggle, { ToggleButton, Positioner } from "./components/Toggle";
const ANIMATION_MS = 250; const ANIMATION_MS = 250;
@@ -170,7 +170,7 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(
{user && ( {user && (
<AccountMenu> <AccountMenu>
{(props) => ( {(props: SidebarButtonProps) => (
<SidebarButton <SidebarButton
{...props} {...props}
showMoreMenu showMoreMenu

View File

@@ -66,8 +66,7 @@ function DocumentLink(
}, [fetchChildDocuments, node, hasChildDocuments, isActiveDocument]); }, [fetchChildDocuments, node, hasChildDocuments, isActiveDocument]);
const pathToNode = React.useMemo( const pathToNode = React.useMemo(
() => () => collection?.pathToDocument(node.id).map((entry) => entry.id),
collection && collection.pathToDocument(node.id).map((entry) => entry.id),
[collection, node] [collection, node]
); );

View File

@@ -5,10 +5,9 @@ import styled from "styled-components";
type Props = { type Props = {
onClick?: React.MouseEventHandler; onClick?: React.MouseEventHandler;
expanded?: boolean; expanded?: boolean;
children: React.ReactNode;
}; };
export function Header({ onClick, expanded, children }: Props) { export const Header: React.FC<Props> = ({ onClick, expanded, children }) => {
return ( return (
<H3> <H3>
<Button onClick={onClick} disabled={!onClick}> <Button onClick={onClick} disabled={!onClick}>
@@ -19,7 +18,7 @@ export function Header({ onClick, expanded, children }: Props) {
</Button> </Button>
</H3> </H3>
); );
} };
const Button = styled.button` const Button = styled.button`
display: inline-flex; display: inline-flex;

View File

@@ -70,7 +70,7 @@ const NavLink = ({
const { pathname: path } = toLocation; const { pathname: path } = toLocation;
// Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202 // Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202
const escapedPath = path && path.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); const escapedPath = path?.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
const match = escapedPath const match = escapedPath
? matchPath(currentLocation.pathname, { ? matchPath(currentLocation.pathname, {
path: escapedPath, path: escapedPath,

View File

@@ -3,7 +3,7 @@ import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import Flex from "~/components/Flex"; import Flex from "~/components/Flex";
type Props = { export type SidebarButtonProps = {
title: React.ReactNode; title: React.ReactNode;
image: React.ReactNode; image: React.ReactNode;
minHeight?: number; minHeight?: number;
@@ -13,7 +13,7 @@ type Props = {
onClick: React.MouseEventHandler<HTMLButtonElement>; onClick: React.MouseEventHandler<HTMLButtonElement>;
}; };
const SidebarButton = React.forwardRef<HTMLButtonElement, Props>( const SidebarButton = React.forwardRef<HTMLButtonElement, SidebarButtonProps>(
( (
{ {
showDisclosure, showDisclosure,
@@ -22,7 +22,7 @@ const SidebarButton = React.forwardRef<HTMLButtonElement, Props>(
title, title,
minHeight = 0, minHeight = 0,
...rest ...rest
}: Props, }: SidebarButtonProps,
ref ref
) => ( ) => (
<Wrapper <Wrapper

View File

@@ -22,9 +22,7 @@ export const SocketContext: any = React.createContext<SocketWithAuthentication |
null null
); );
type Props = RootStore & { type Props = RootStore;
children: React.ReactNode;
};
@observer @observer
class SocketProvider extends React.Component<Props> { class SocketProvider extends React.Component<Props> {
@@ -46,7 +44,7 @@ class SocketProvider extends React.Component<Props> {
} }
checkConnection = () => { checkConnection = () => {
if (this.socket && this.socket.disconnected && getPageVisible()) { if (this.socket?.disconnected && getPageVisible()) {
// null-ifying this reference is important, do not remove. Without it // null-ifying this reference is important, do not remove. Without it
// references to old sockets are potentially held in context // references to old sockets are potentially held in context
this.socket.close(); this.socket.close();
@@ -102,10 +100,9 @@ class SocketProvider extends React.Component<Props> {
// connection may have failed (caused by proxy, firewall, browser, ...) // connection may have failed (caused by proxy, firewall, browser, ...)
this.socket.on("reconnect_attempt", () => { this.socket.on("reconnect_attempt", () => {
if (this.socket) { if (this.socket) {
this.socket.io.opts.transports = this.socket.io.opts.transports = auth?.team?.domain
auth.team && auth.team.domain ? ["websocket"]
? ["websocket"] : ["websocket", "polling"];
: ["websocket", "polling"];
} }
}); });
@@ -210,10 +207,7 @@ class SocketProvider extends React.Component<Props> {
// if we already have the latest version (it was us that performed // if we already have the latest version (it was us that performed
// the change) then we don't need to update anything either. // the change) then we don't need to update anything either.
if ( if (collection?.updatedAt === collectionDescriptor.updatedAt) {
collection &&
collection.updatedAt === collectionDescriptor.updatedAt
) {
continue; continue;
} }

View File

@@ -2,7 +2,6 @@ import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
type Props = { type Props = {
children: React.ReactNode;
sticky?: boolean; sticky?: boolean;
}; };
@@ -34,7 +33,7 @@ const Background = styled.div<{ sticky?: boolean }>`
z-index: 1; z-index: 1;
`; `;
const Subheading = ({ children, sticky, ...rest }: Props) => { const Subheading: React.FC<Props> = ({ children, sticky, ...rest }) => {
return ( return (
<Background sticky={sticky}> <Background sticky={sticky}>
<H3 {...rest}> <H3 {...rest}>

View File

@@ -9,7 +9,6 @@ type Props = Omit<
> & { > & {
to: string; to: string;
exact?: boolean; exact?: boolean;
children: React.ReactNode;
}; };
const TabLink = styled(NavLinkWithChildrenFunc)` const TabLink = styled(NavLinkWithChildrenFunc)`
@@ -45,7 +44,7 @@ const transition = {
damping: 30, damping: 30,
}; };
export default function Tab({ children, ...rest }: Props) { const Tab: React.FC<Props> = ({ children, ...rest }) => {
const theme = useTheme(); const theme = useTheme();
const activeStyle = { const activeStyle = {
color: theme.textSecondary, color: theme.textSecondary,
@@ -67,4 +66,6 @@ export default function Tab({ children, ...rest }: Props) {
)} )}
</TabLink> </TabLink>
); );
} };
export default Tab;

View File

@@ -56,7 +56,7 @@ export const Separator = styled.span`
margin-top: 6px; margin-top: 6px;
`; `;
const Tabs = ({ children }: { children: React.ReactNode }) => { const Tabs: React.FC = ({ children }) => {
const ref = React.useRef<any>(); const ref = React.useRef<any>();
const [shadowVisible, setShadow] = React.useState(false); const [shadowVisible, setShadow] = React.useState(false);
const { width } = useWindowSize(); const { width } = useWindowSize();

View File

@@ -6,11 +6,7 @@ import useMediaQuery from "~/hooks/useMediaQuery";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import GlobalStyles from "~/styles/globals"; import GlobalStyles from "~/styles/globals";
type Props = { const Theme: React.FC = ({ children }) => {
children: React.ReactNode;
};
function Theme({ children }: Props) {
const { ui } = useStores(); const { ui } = useStores();
const resolvedTheme = ui.resolvedTheme === "dark" ? dark : light; const resolvedTheme = ui.resolvedTheme === "dark" ? dark : light;
const resolvedMobileTheme = const resolvedMobileTheme =
@@ -37,6 +33,6 @@ function Theme({ children }: Props) {
</> </>
</ThemeProvider> </ThemeProvider>
); );
} };
export default observer(Theme); export default observer(Theme);

View File

@@ -139,7 +139,7 @@ class CommandMenu<T = MenuItem> extends React.Component<Props<T>, State> {
this.setState({ this.setState({
selectedIndex: Math.max( selectedIndex: Math.max(
0, 0,
prev && prev.name === "separator" ? prevIndex - 1 : prevIndex prev?.name === "separator" ? prevIndex - 1 : prevIndex
), ),
}); });
} else { } else {
@@ -162,7 +162,7 @@ class CommandMenu<T = MenuItem> extends React.Component<Props<T>, State> {
this.setState({ this.setState({
selectedIndex: Math.min( selectedIndex: Math.min(
next && next.name === "separator" ? nextIndex + 1 : nextIndex, next?.name === "separator" ? nextIndex + 1 : nextIndex,
total total
), ),
}); });

View File

@@ -191,8 +191,7 @@ export default class SelectionToolbar extends React.Component<Props> {
const isTableSelection = colIndex !== undefined && rowIndex !== undefined; const isTableSelection = colIndex !== undefined && rowIndex !== undefined;
const link = isMarkActive(state.schema.marks.link)(state); const link = isMarkActive(state.schema.marks.link)(state);
const range = getMarkRange(selection.$from, state.schema.marks.link); const range = getMarkRange(selection.$from, state.schema.marks.link);
const isImageSelection = const isImageSelection = selection.node?.type?.name === "image";
selection.node && selection.node.type.name === "image";
let isTextSelection = false; let isTextSelection = false;
let items: MenuItem[] = []; let items: MenuItem[] = [];

View File

@@ -3,11 +3,10 @@ import styled from "styled-components";
import Tooltip from "~/components/Tooltip"; import Tooltip from "~/components/Tooltip";
type Props = { type Props = {
children: React.ReactNode;
tooltip?: string; tooltip?: string;
}; };
const WrappedTooltip = ({ children, tooltip }: Props) => ( const WrappedTooltip: React.FC<Props> = ({ children, tooltip }) => (
<Tooltip offset="0, 8" delay={150} tooltip={tooltip} placement="top"> <Tooltip offset="0, 8" delay={150} tooltip={tooltip} placement="top">
<TooltipContent>{children}</TooltipContent> <TooltipContent>{children}</TooltipContent>
</Tooltip> </Tooltip>

View File

@@ -29,6 +29,7 @@ import Zapier from "~/scenes/Settings/Zapier";
import SlackIcon from "~/components/SlackIcon"; import SlackIcon from "~/components/SlackIcon";
import ZapierIcon from "~/components/ZapierIcon"; import ZapierIcon from "~/components/ZapierIcon";
import env from "~/env"; import env from "~/env";
import isHosted from "~/utils/isHosted";
import useCurrentTeam from "./useCurrentTeam"; import useCurrentTeam from "./useCurrentTeam";
import usePolicy from "./usePolicy"; import usePolicy from "./usePolicy";
@@ -61,8 +62,6 @@ type ConfigType = {
[key in SettingsPage]: ConfigItem; [key in SettingsPage]: ConfigItem;
}; };
const isHosted = env.DEPLOYMENT === "hosted";
const useAuthorizedSettingsConfig = () => { const useAuthorizedSettingsConfig = () => {
const team = useCurrentTeam(); const team = useCurrentTeam();
const can = usePolicy(team.id); const can = usePolicy(team.id);

View File

@@ -37,7 +37,7 @@ if ("serviceWorker" in window.navigator) {
} }
); );
if (maybePromise && maybePromise.then) { if (maybePromise?.then) {
maybePromise maybePromise
.then((registration) => { .then((registration) => {
console.log("SW registered: ", registration); console.log("SW registered: ", registration);

View File

@@ -18,11 +18,7 @@ import usePrevious from "~/hooks/usePrevious";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import separator from "~/menus/separator"; import separator from "~/menus/separator";
type Props = { const AccountMenu: React.FC = ({ children }) => {
children: (props: any) => React.ReactNode;
};
function AccountMenu(props: Props) {
const menu = useMenuState({ const menu = useMenuState({
placement: "bottom-end", placement: "bottom-end",
modal: true, modal: true,
@@ -55,12 +51,12 @@ function AccountMenu(props: Props) {
return ( return (
<> <>
<MenuButton {...menu}>{props.children}</MenuButton> <MenuButton {...menu}>{children}</MenuButton>
<ContextMenu {...menu} aria-label={t("Account")}> <ContextMenu {...menu} aria-label={t("Account")}>
<Template {...menu} items={undefined} actions={actions} /> <Template {...menu} items={undefined} actions={actions} />
</ContextMenu> </ContextMenu>
</> </>
); );
} };
export default observer(AccountMenu); export default observer(AccountMenu);

View File

@@ -13,11 +13,7 @@ import useSessions from "~/hooks/useSessions";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import separator from "~/menus/separator"; import separator from "~/menus/separator";
type Props = { const OrganizationMenu: React.FC = ({ children }) => {
children: (props: any) => React.ReactNode;
};
function OrganizationMenu(props: Props) {
const [sessions] = useSessions(); const [sessions] = useSessions();
const menu = useMenuState({ const menu = useMenuState({
unstable_offset: [4, -4], unstable_offset: [4, -4],
@@ -65,13 +61,13 @@ function OrganizationMenu(props: Props) {
return ( return (
<> <>
<MenuButton {...menu}>{props.children}</MenuButton> <MenuButton {...menu}>{children}</MenuButton>
<ContextMenu {...menu} aria-label={t("Account")}> <ContextMenu {...menu} aria-label={t("Account")}>
<Template {...menu} items={undefined} actions={actions} /> <Template {...menu} items={undefined} actions={actions} />
</ContextMenu> </ContextMenu>
</> </>
); );
} };
const Logo = styled("img")` const Logo = styled("img")`
border-radius: 2px; border-radius: 2px;

View File

@@ -9,13 +9,17 @@ import useImportDocument from "~/hooks/useImportDocument";
import useToasts from "~/hooks/useToasts"; import useToasts from "~/hooks/useToasts";
type Props = { type Props = {
children: React.ReactNode;
disabled: boolean; disabled: boolean;
accept: string; accept: string;
collectionId: string; collectionId: string;
}; };
function DropToImport({ children, disabled, accept, collectionId }: Props) { const DropToImport: React.FC<Props> = ({
children,
disabled,
accept,
collectionId,
}) => {
const { handleFiles, isImporting } = useImportDocument(collectionId); const { handleFiles, isImporting } = useImportDocument(collectionId);
const { showToast } = useToasts(); const { showToast } = useToasts();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -53,7 +57,7 @@ function DropToImport({ children, disabled, accept, collectionId }: Props) {
)} )}
</Dropzone> </Dropzone>
); );
} };
const DropMessage = styled(Text)` const DropMessage = styled(Text)`
opacity: 0; opacity: 0;

View File

@@ -3,7 +3,6 @@ import UiStore from "~/stores/UiStore";
type Props = { type Props = {
ui: UiStore; ui: UiStore;
children?: React.ReactNode;
}; };
class HideSidebar extends React.Component<Props> { class HideSidebar extends React.Component<Props> {

View File

@@ -4,7 +4,6 @@ import Document from "~/models/Document";
const MARK_AS_VIEWED_AFTER = 3 * 1000; const MARK_AS_VIEWED_AFTER = 3 * 1000;
type Props = { type Props = {
document: Document; document: Document;
children?: React.ReactNode;
}; };
class MarkAsViewed extends React.Component<Props> { class MarkAsViewed extends React.Component<Props> {

View File

@@ -6,7 +6,6 @@ type Props = {
documentId: string; documentId: string;
shareId: string; shareId: string;
sharedTree: NavigationNode | undefined; sharedTree: NavigationNode | undefined;
children?: React.ReactNode;
}; };
function pathToDocument( function pathToDocument(
@@ -38,12 +37,12 @@ function pathToDocument(
return path; return path;
} }
const PublicBreadcrumb = ({ const PublicBreadcrumb: React.FC<Props> = ({
documentId, documentId,
shareId, shareId,
sharedTree, sharedTree,
children, children,
}: Props) => { }) => {
const items: MenuInternalLink[] = React.useMemo( const items: MenuInternalLink[] = React.useMemo(
() => () =>
pathToDocument(sharedTree, documentId) pathToDocument(sharedTree, documentId)

View File

@@ -20,8 +20,7 @@ function ShareButton({ document }: Props) {
const share = shares.getByDocumentId(document.id); const share = shares.getByDocumentId(document.id);
const sharedParent = shares.getByDocumentParents(document.id); const sharedParent = shares.getByDocumentParents(document.id);
const isPubliclyShared = const isPubliclyShared =
(share && share.published) || share?.published || (sharedParent?.published && !document.isDraft);
(sharedParent && sharedParent.published && !document.isDraft);
const popover = usePopoverState({ const popover = usePopoverState({
gutter: 0, gutter: 0,

View File

@@ -3,7 +3,6 @@ import { USER_PRESENCE_INTERVAL } from "@shared/constants";
import { SocketContext } from "~/components/SocketProvider"; import { SocketContext } from "~/components/SocketProvider";
type Props = { type Props = {
children?: React.ReactNode;
documentId: string; documentId: string;
isEditing: boolean; isEditing: boolean;
}; };

View File

@@ -20,12 +20,11 @@ import env from "~/env";
import useQuery from "~/hooks/useQuery"; import useQuery from "~/hooks/useQuery";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import { isCustomDomain } from "~/utils/domains"; import { isCustomDomain } from "~/utils/domains";
import isHosted from "~/utils/isHosted";
import { changeLanguage, detectLanguage } from "~/utils/language"; import { changeLanguage, detectLanguage } from "~/utils/language";
import Notices from "./Notices"; import Notices from "./Notices";
import Provider from "./Provider"; import Provider from "./Provider";
const isHosted = env.DEPLOYMENT === "hosted";
function Header({ config }: { config?: Config | undefined }) { function Header({ config }: { config?: Config | undefined }) {
const { t } = useTranslation(); const { t } = useTranslation();
const isSubdomain = !!config?.hostname; const isSubdomain = !!config?.hostname;
@@ -160,7 +159,7 @@ function Login() {
<Centered align="center" justify="center" column auto> <Centered align="center" justify="center" column auto>
<PageTitle title={t("Login")} /> <PageTitle title={t("Login")} />
<Logo> <Logo>
{env.TEAM_LOGO && env.DEPLOYMENT !== "hosted" ? ( {env.TEAM_LOGO && !isHosted ? (
<TeamLogo src={env.TEAM_LOGO} /> <TeamLogo src={env.TEAM_LOGO} />
) : ( ) : (
<OutlineLogo size={38} fill="currentColor" /> <OutlineLogo size={38} fill="currentColor" />

View File

@@ -13,6 +13,7 @@ import env from "~/env";
import useCurrentTeam from "~/hooks/useCurrentTeam"; import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts"; import useToasts from "~/hooks/useToasts";
import isHosted from "~/utils/isHosted";
import ImageInput from "./components/ImageInput"; import ImageInput from "./components/ImageInput";
import SettingRow from "./components/SettingRow"; import SettingRow from "./components/SettingRow";
@@ -133,7 +134,7 @@ function Details() {
/> />
</SettingRow> </SettingRow>
<SettingRow <SettingRow
visible={env.SUBDOMAINS_ENABLED && env.DEPLOYMENT === "hosted"} visible={env.SUBDOMAINS_ENABLED && isHosted}
label={t("Subdomain")} label={t("Subdomain")}
name="subdomain" name="subdomain"
description={ description={

View File

@@ -13,6 +13,7 @@ import env from "~/env";
import useCurrentUser from "~/hooks/useCurrentUser"; import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts"; import useToasts from "~/hooks/useToasts";
import isHosted from "~/utils/isHosted";
import SettingRow from "./components/SettingRow"; import SettingRow from "./components/SettingRow";
function Notifications() { function Notifications() {
@@ -47,7 +48,7 @@ function Notifications() {
separator: true, separator: true,
}, },
{ {
visible: env.DEPLOYMENT === "hosted", visible: isHosted,
event: "emails.onboarding", event: "emails.onboarding",
title: t("Getting started"), title: t("Getting started"),
description: t( description: t(
@@ -55,7 +56,7 @@ function Notifications() {
), ),
}, },
{ {
visible: env.DEPLOYMENT === "hosted", visible: isHosted,
event: "emails.features", event: "emails.features",
title: t("New features"), title: t("New features"),
description: t("Receive an email when new features of note are added"), description: t("Receive an email when new features of note are added"),

View File

@@ -17,7 +17,6 @@ import { uploadFile, dataUrlToBlob } from "~/utils/files";
const EMPTY_OBJECT = {}; const EMPTY_OBJECT = {};
export type Props = { export type Props = {
children?: React.ReactNode;
onSuccess: (url: string) => void | Promise<void>; onSuccess: (url: string) => void | Promise<void>;
onError: (error: string) => void; onError: (error: string) => void;
submitText?: string; submitText?: string;

View File

@@ -146,7 +146,7 @@ export default class AuthStore {
@action @action
fetchConfig = async () => { fetchConfig = async () => {
const res = await client.post("/auth.config"); const res = await client.post("/auth.config");
invariant(res && res.data, "Config not available"); invariant(res?.data, "Config not available");
this.config = res.data; this.config = res.data;
}; };
@@ -154,7 +154,7 @@ export default class AuthStore {
fetch = async () => { fetch = async () => {
try { try {
const res = await client.post("/auth.info"); const res = await client.post("/auth.info");
invariant(res && res.data, "Auth not available"); invariant(res?.data, "Auth not available");
runInAction("AuthStore#fetch", () => { runInAction("AuthStore#fetch", () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);
const { user, team } = res.data; const { user, team } = res.data;
@@ -212,7 +212,7 @@ export default class AuthStore {
try { try {
const res = await client.post(`/users.update`, params); const res = await client.post(`/users.update`, params);
invariant(res && res.data, "User response not available"); invariant(res?.data, "User response not available");
runInAction("AuthStore#updateUser", () => { runInAction("AuthStore#updateUser", () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);
this.user = new User(res.data, this); this.user = new User(res.data, this);
@@ -235,7 +235,7 @@ export default class AuthStore {
try { try {
const res = await client.post(`/team.update`, params); const res = await client.post(`/team.update`, params);
invariant(res && res.data, "Team response not available"); invariant(res?.data, "Team response not available");
runInAction("AuthStore#updateTeam", () => { runInAction("AuthStore#updateTeam", () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);
this.team = new Team(res.data, this); this.team = new Team(res.data, this);

View File

@@ -138,7 +138,7 @@ export default class BaseStore<T extends BaseModel> {
...options, ...options,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return this.add(res.data); return this.add(res.data);
} finally { } finally {
@@ -163,7 +163,7 @@ export default class BaseStore<T extends BaseModel> {
...options, ...options,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return this.add(res.data); return this.add(res.data);
} finally { } finally {
@@ -206,7 +206,7 @@ export default class BaseStore<T extends BaseModel> {
const res = await client.post(`/${this.apiEndpoint}.info`, { const res = await client.post(`/${this.apiEndpoint}.info`, {
id, id,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return this.add(res.data); return this.add(res.data);
} catch (err) { } catch (err) {
@@ -230,7 +230,7 @@ export default class BaseStore<T extends BaseModel> {
try { try {
const res = await client.post(`/${this.apiEndpoint}.list`, params); const res = await client.post(`/${this.apiEndpoint}.list`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`list#${this.modelName}`, () => { runInAction(`list#${this.modelName}`, () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);

View File

@@ -21,7 +21,7 @@ export default class CollectionGroupMembershipsStore extends BaseStore<
try { try {
const res = await client.post(`/collections.group_memberships`, params); const res = await client.post(`/collections.group_memberships`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`CollectionGroupMembershipsStore#fetchPage`, () => { runInAction(`CollectionGroupMembershipsStore#fetchPage`, () => {
res.data.groups.forEach(this.rootStore.groups.add); res.data.groups.forEach(this.rootStore.groups.add);
res.data.collectionGroupMemberships.forEach(this.add); res.data.collectionGroupMemberships.forEach(this.add);
@@ -48,7 +48,7 @@ export default class CollectionGroupMembershipsStore extends BaseStore<
groupId, groupId,
permission, permission,
}); });
invariant(res && res.data, "Membership data should be available"); invariant(res?.data, "Membership data should be available");
const cgm = res.data.collectionGroupMemberships.map(this.add); const cgm = res.data.collectionGroupMemberships.map(this.add);
return cgm[0]; return cgm[0];

View File

@@ -111,7 +111,7 @@ export default class CollectionsStore extends BaseStore<Collection> {
id: collectionId, id: collectionId,
index, index,
}); });
invariant(res && res.success, "Collection could not be moved"); invariant(res?.success, "Collection could not be moved");
const collection = this.get(collectionId); const collection = this.get(collectionId);
if (collection) { if (collection) {
@@ -153,7 +153,7 @@ export default class CollectionsStore extends BaseStore<Collection> {
const res = await client.post(`/collections.info`, { const res = await client.post(`/collections.info`, {
id, id,
}); });
invariant(res && res.data, "Collection not available"); invariant(res?.data, "Collection not available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return this.add(res.data); return this.add(res.data);
} catch (err) { } catch (err) {

View File

@@ -239,7 +239,7 @@ export default class DocumentsStore extends BaseStore<Document> {
const res = await client.post(`/documents.list`, { const res = await client.post(`/documents.list`, {
backlinkDocumentId: documentId, backlinkDocumentId: documentId,
}); });
invariant(res && res.data, "Document list not available"); invariant(res?.data, "Document list not available");
const { data } = res; const { data } = res;
runInAction("DocumentsStore#fetchBacklinks", () => { runInAction("DocumentsStore#fetchBacklinks", () => {
@@ -271,7 +271,7 @@ export default class DocumentsStore extends BaseStore<Document> {
const res = await client.post(`/documents.list`, { const res = await client.post(`/documents.list`, {
parentDocumentId: documentId, parentDocumentId: documentId,
}); });
invariant(res && res.data, "Document list not available"); invariant(res?.data, "Document list not available");
const { data } = res; const { data } = res;
runInAction("DocumentsStore#fetchChildDocuments", () => { runInAction("DocumentsStore#fetchChildDocuments", () => {
@@ -289,7 +289,7 @@ export default class DocumentsStore extends BaseStore<Document> {
try { try {
const res = await client.post(`/documents.${request}`, options); const res = await client.post(`/documents.${request}`, options);
invariant(res && res.data, "Document list not available"); invariant(res?.data, "Document list not available");
runInAction("DocumentsStore#fetchNamedPage", () => { runInAction("DocumentsStore#fetchNamedPage", () => {
res.data.forEach(this.add); res.data.forEach(this.add);
this.addPolicies(res.policies); this.addPolicies(res.policies);
@@ -375,7 +375,7 @@ export default class DocumentsStore extends BaseStore<Document> {
const res = await client.get("/documents.search_titles", { const res = await client.get("/documents.search_titles", {
query, query,
}); });
invariant(res && res.data, "Search response should be available"); invariant(res?.data, "Search response should be available");
// add the documents and associated policies to the store // add the documents and associated policies to the store
res.data.forEach(this.add); res.data.forEach(this.add);
this.addPolicies(res.policies); this.addPolicies(res.policies);
@@ -392,7 +392,7 @@ export default class DocumentsStore extends BaseStore<Document> {
...compactedOptions, ...compactedOptions,
query, query,
}); });
invariant(res && res.data, "Search response should be available"); invariant(res?.data, "Search response should be available");
// add the documents and associated policies to the store // add the documents and associated policies to the store
res.data.forEach((result: SearchResult) => this.add(result.document)); res.data.forEach((result: SearchResult) => this.add(result.document));
@@ -443,7 +443,7 @@ export default class DocumentsStore extends BaseStore<Document> {
const res = await client.post("/documents.templatize", { const res = await client.post("/documents.templatize", {
id, id,
}); });
invariant(res && res.data, "Document not available"); invariant(res?.data, "Document not available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
this.add(res.data); this.add(res.data);
return this.data.get(res.data.id); return this.data.get(res.data.id);
@@ -485,7 +485,7 @@ export default class DocumentsStore extends BaseStore<Document> {
apiVersion: 2, apiVersion: 2,
}); });
invariant(res && res.data, "Document not available"); invariant(res?.data, "Document not available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
this.add(res.data.document); this.add(res.data.document);
@@ -524,7 +524,7 @@ export default class DocumentsStore extends BaseStore<Document> {
parentDocumentId, parentDocumentId,
index: index, index: index,
}); });
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
res.data.documents.forEach(this.add); res.data.documents.forEach(this.add);
res.data.collections.forEach(this.rootStore.collections.add); res.data.collections.forEach(this.rootStore.collections.add);
this.addPolicies(res.policies); this.addPolicies(res.policies);
@@ -547,7 +547,7 @@ export default class DocumentsStore extends BaseStore<Document> {
)}${append}`, )}${append}`,
text: document.text, text: document.text,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
const collection = this.getCollectionForDocument(document); const collection = this.getCollectionForDocument(document);
if (collection) { if (collection) {
collection.refresh(); collection.refresh();
@@ -613,7 +613,7 @@ export default class DocumentsStore extends BaseStore<Document> {
} }
}); });
const res = await client.post("/documents.import", formData); const res = await client.post("/documents.import", formData);
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return this.add(res.data); return this.add(res.data);
}; };
@@ -680,7 +680,7 @@ export default class DocumentsStore extends BaseStore<Document> {
id: document.id, id: document.id,
}); });
runInAction("Document#archive", () => { runInAction("Document#archive", () => {
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
document.updateFromJson(res.data); document.updateFromJson(res.data);
this.addPolicies(res.policies); this.addPolicies(res.policies);
}); });
@@ -704,7 +704,7 @@ export default class DocumentsStore extends BaseStore<Document> {
collectionId: options.collectionId, collectionId: options.collectionId,
}); });
runInAction("Document#restore", () => { runInAction("Document#restore", () => {
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
document.updateFromJson(res.data); document.updateFromJson(res.data);
this.addPolicies(res.policies); this.addPolicies(res.policies);
}); });
@@ -720,7 +720,7 @@ export default class DocumentsStore extends BaseStore<Document> {
id: document.id, id: document.id,
}); });
runInAction("Document#unpublish", () => { runInAction("Document#unpublish", () => {
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
document.updateFromJson(res.data); document.updateFromJson(res.data);
this.addPolicies(res.policies); this.addPolicies(res.policies);
}); });

View File

@@ -20,7 +20,7 @@ export default class GroupMembershipsStore extends BaseStore<GroupMembership> {
try { try {
const res = await client.post(`/groups.memberships`, params); const res = await client.post(`/groups.memberships`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`GroupMembershipsStore#fetchPage`, () => { runInAction(`GroupMembershipsStore#fetchPage`, () => {
res.data.users.forEach(this.rootStore.users.add); res.data.users.forEach(this.rootStore.users.add);
res.data.groupMemberships.forEach(this.add); res.data.groupMemberships.forEach(this.add);
@@ -38,7 +38,7 @@ export default class GroupMembershipsStore extends BaseStore<GroupMembership> {
id: groupId, id: groupId,
userId, userId,
}); });
invariant(res && res.data, "Group Membership data should be available"); invariant(res?.data, "Group Membership data should be available");
res.data.users.forEach(this.rootStore.users.add); res.data.users.forEach(this.rootStore.users.add);
res.data.groups.forEach(this.rootStore.groups.add); res.data.groups.forEach(this.rootStore.groups.add);
@@ -52,7 +52,7 @@ export default class GroupMembershipsStore extends BaseStore<GroupMembership> {
id: groupId, id: groupId,
userId, userId,
}); });
invariant(res && res.data, "Group Membership data should be available"); invariant(res?.data, "Group Membership data should be available");
this.remove(`${userId}-${groupId}`); this.remove(`${userId}-${groupId}`);
runInAction(`GroupMembershipsStore#delete`, () => { runInAction(`GroupMembershipsStore#delete`, () => {
res.data.groups.forEach(this.rootStore.groups.add); res.data.groups.forEach(this.rootStore.groups.add);

View File

@@ -26,7 +26,7 @@ export default class GroupsStore extends BaseStore<Group> {
try { try {
const res = await client.post(`/groups.list`, params); const res = await client.post(`/groups.list`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`GroupsStore#fetchPage`, () => { runInAction(`GroupsStore#fetchPage`, () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);
res.data.groups.forEach(this.add); res.data.groups.forEach(this.add);

View File

@@ -19,7 +19,7 @@ export default class MembershipsStore extends BaseStore<Membership> {
try { try {
const res = await client.post(`/collections.memberships`, params); const res = await client.post(`/collections.memberships`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`/collections.memberships`, () => { runInAction(`/collections.memberships`, () => {
res.data.users.forEach(this.rootStore.users.add); res.data.users.forEach(this.rootStore.users.add);
res.data.memberships.forEach(this.add); res.data.memberships.forEach(this.add);
@@ -46,7 +46,7 @@ export default class MembershipsStore extends BaseStore<Membership> {
userId, userId,
permission, permission,
}); });
invariant(res && res.data, "Membership data should be available"); invariant(res?.data, "Membership data should be available");
res.data.users.forEach(this.rootStore.users.add); res.data.users.forEach(this.rootStore.users.add);
const memberships = res.data.memberships.map(this.add); const memberships = res.data.memberships.map(this.add);

View File

@@ -19,7 +19,7 @@ export default class PinsStore extends BaseStore<Pin> {
try { try {
const res = await client.post(`/pins.list`, params); const res = await client.post(`/pins.list`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`PinsStore#fetchPage`, () => { runInAction(`PinsStore#fetchPage`, () => {
res.data.documents.forEach(this.rootStore.documents.add); res.data.documents.forEach(this.rootStore.documents.add);
res.data.pins.forEach(this.add); res.data.pins.forEach(this.add);

View File

@@ -53,7 +53,7 @@ export default class RevisionsStore extends BaseStore<Revision> {
try { try {
const res = await client.post("/revisions.list", options); const res = await client.post("/revisions.list", options);
invariant(res && res.data, "Document revisions not available"); invariant(res?.data, "Document revisions not available");
runInAction("RevisionsStore#fetchPage", () => { runInAction("RevisionsStore#fetchPage", () => {
res.data.forEach(this.add); res.data.forEach(this.add);
this.isLoaded = true; this.isLoaded = true;

View File

@@ -65,7 +65,7 @@ export default class SharesStore extends BaseStore<Share> {
if (isUndefined(res)) { if (isUndefined(res)) {
return; return;
} }
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.addPolicies(res.policies); this.addPolicies(res.policies);
return res.data.shares.map(this.add); return res.data.shares.map(this.add);
} finally { } finally {
@@ -92,7 +92,7 @@ export default class SharesStore extends BaseStore<Share> {
for (const parentId of parentIds) { for (const parentId of parentIds) {
const share = this.getByDocumentId(parentId); const share = this.getByDocumentId(parentId);
if (share && share.includeChildDocuments && share.published) { if (share?.includeChildDocuments && share.published) {
return share; return share;
} }
} }

View File

@@ -17,7 +17,7 @@ export default class StarsStore extends BaseStore<Star> {
try { try {
const res = await client.post(`/stars.list`, params); const res = await client.post(`/stars.list`, params);
invariant(res && res.data, "Data not available"); invariant(res?.data, "Data not available");
runInAction(`StarsStore#fetchPage`, () => { runInAction(`StarsStore#fetchPage`, () => {
res.data.documents.forEach(this.rootStore.documents.add); res.data.documents.forEach(this.rootStore.documents.add);
res.data.stars.forEach(this.add); res.data.stars.forEach(this.add);

View File

@@ -21,7 +21,7 @@ export default class ToastsStore {
} }
const lastToast = this.toasts.get(this.lastToastId); const lastToast = this.toasts.get(this.lastToastId);
if (lastToast && lastToast.message === message) { if (lastToast?.message === message) {
this.toasts.set(this.lastToastId, { this.toasts.set(this.lastToastId, {
...lastToast, ...lastToast,
reoccurring: lastToast.reoccurring ? ++lastToast.reoccurring : 1, reoccurring: lastToast.reoccurring ? ++lastToast.reoccurring : 1,

View File

@@ -126,7 +126,7 @@ export default class UsersStore extends BaseStore<User> {
const res = await client.post(`/users.invite`, { const res = await client.post(`/users.invite`, {
invites, invites,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
runInAction(`invite`, () => { runInAction(`invite`, () => {
res.data.users.forEach(this.add); res.data.users.forEach(this.add);
this.counts.invited += res.data.sent.length; this.counts.invited += res.data.sent.length;
@@ -140,7 +140,7 @@ export default class UsersStore extends BaseStore<User> {
const res = await client.post(`/users.count`, { const res = await client.post(`/users.count`, {
teamId, teamId,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
this.counts = res.data.counts; this.counts = res.data.counts;
return res.data; return res.data;
}; };
@@ -268,7 +268,7 @@ export default class UsersStore extends BaseStore<User> {
id: user.id, id: user.id,
to, to,
}); });
invariant(res && res.data, "Data should be available"); invariant(res?.data, "Data should be available");
runInAction(`UsersStore#${action}`, () => { runInAction(`UsersStore#${action}`, () => {
this.addPolicies(res.policies); this.addPolicies(res.policies);
this.add(res.data); this.add(res.data);

View File

@@ -3,7 +3,7 @@ import invariant from "invariant";
import { map, trim } from "lodash"; import { map, trim } from "lodash";
import EDITOR_VERSION from "@shared/editor/version"; import EDITOR_VERSION from "@shared/editor/version";
import stores from "~/stores"; import stores from "~/stores";
import env from "~/env"; import isHosted from "~/utils/isHosted";
import download from "./download"; import download from "./download";
import { import {
AuthorizationError, AuthorizationError,
@@ -21,7 +21,6 @@ type Options = {
}; };
const fetchWithRetry = retry(fetch); const fetchWithRetry = retry(fetch);
const isHosted = env.DEPLOYMENT === "hosted";
class ApiClient { class ApiClient {
baseUrl: string; baseUrl: string;

5
app/utils/isHosted.ts Normal file
View File

@@ -0,0 +1,5 @@
import env from "~/env";
const isHosted = env.DEPLOYMENT === "hosted";
export default isHosted;