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

View File

@@ -15,7 +15,7 @@ type Props = {
const Authenticated = ({ children }: Props) => {
const { auth } = useStores();
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
// 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) => ({
showing: state.visualState !== "hidden",
}));
@@ -77,7 +77,7 @@ function KBarPortal({ children }: { children: React.ReactNode }) {
}
return <Portal>{children}</Portal>;
}
};
const Hint = styled(Text)`
display: flex;

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,7 @@ import CenteredContent from "~/components/CenteredContent";
import PageTitle from "~/components/PageTitle";
import Text from "~/components/Text";
import env from "~/env";
import isHosted from "~/utils/isHosted";
type Props = WithTranslation & {
reloadOnChunkMissing?: boolean;
@@ -61,7 +62,7 @@ class ErrorBoundary extends React.Component<Props> {
if (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/);
if (isChunkError) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -70,7 +70,7 @@ const NavLink = ({
const { pathname: path } = toLocation;
// 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
? matchPath(currentLocation.pathname, {
path: escapedPath,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,6 +13,7 @@ import env from "~/env";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import isHosted from "~/utils/isHosted";
import SettingRow from "./components/SettingRow";
function Notifications() {
@@ -47,7 +48,7 @@ function Notifications() {
separator: true,
},
{
visible: env.DEPLOYMENT === "hosted",
visible: isHosted,
event: "emails.onboarding",
title: t("Getting started"),
description: t(
@@ -55,7 +56,7 @@ function Notifications() {
),
},
{
visible: env.DEPLOYMENT === "hosted",
visible: isHosted,
event: "emails.features",
title: t("New features"),
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 = {};
export type Props = {
children?: React.ReactNode;
onSuccess: (url: string) => void | Promise<void>;
onError: (error: string) => void;
submitText?: string;

View File

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

View File

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

View File

@@ -21,7 +21,7 @@ export default class CollectionGroupMembershipsStore extends BaseStore<
try {
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`, () => {
res.data.groups.forEach(this.rootStore.groups.add);
res.data.collectionGroupMemberships.forEach(this.add);
@@ -48,7 +48,7 @@ export default class CollectionGroupMembershipsStore extends BaseStore<
groupId,
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);
return cgm[0];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,7 @@ export default class RevisionsStore extends BaseStore<Revision> {
try {
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", () => {
res.data.forEach(this.add);
this.isLoaded = true;

View File

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

View File

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

View File

@@ -21,7 +21,7 @@ export default class ToastsStore {
}
const lastToast = this.toasts.get(this.lastToastId);
if (lastToast && lastToast.message === message) {
if (lastToast?.message === message) {
this.toasts.set(this.lastToastId, {
...lastToast,
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`, {
invites,
});
invariant(res && res.data, "Data should be available");
invariant(res?.data, "Data should be available");
runInAction(`invite`, () => {
res.data.users.forEach(this.add);
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`, {
teamId,
});
invariant(res && res.data, "Data should be available");
invariant(res?.data, "Data should be available");
this.counts = res.data.counts;
return res.data;
};
@@ -268,7 +268,7 @@ export default class UsersStore extends BaseStore<User> {
id: user.id,
to,
});
invariant(res && res.data, "Data should be available");
invariant(res?.data, "Data should be available");
runInAction(`UsersStore#${action}`, () => {
this.addPolicies(res.policies);
this.add(res.data);

View File

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