Move toasts to sonner (#6053)

This commit is contained in:
Tom Moor
2023-10-22 17:30:24 -04:00
committed by GitHub
parent 389297a337
commit ef76405bd6
92 changed files with 363 additions and 1015 deletions

View File

@@ -1,11 +1,11 @@
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Input from "~/components/Input";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
onSubmit: () => void;
@@ -15,7 +15,6 @@ function APITokenNew({ onSubmit }: Props) {
const [name, setName] = React.useState("");
const [isSaving, setIsSaving] = React.useState(false);
const { apiKeys } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const handleSubmit = React.useCallback(
@@ -27,21 +26,15 @@ function APITokenNew({ onSubmit }: Props) {
await apiKeys.create({
name,
});
showToast(
t("API token created", {
type: "success",
})
);
toast.success(t("API token created"));
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}
},
[t, showToast, name, onSubmit, apiKeys]
[t, name, onSubmit, apiKeys]
);
const handleNameChange = React.useCallback((event) => {

View File

@@ -2,11 +2,11 @@ import { observer } from "mobx-react";
import * as React from "react";
import Dropzone from "react-dropzone";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import styled, { css } from "styled-components";
import LoadingIndicator from "~/components/LoadingIndicator";
import Text from "~/components/Text";
import useImportDocument from "~/hooks/useImportDocument";
import useToasts from "~/hooks/useToasts";
type Props = {
disabled: boolean;
@@ -22,17 +22,13 @@ const DropToImport: React.FC<Props> = ({
collectionId,
}: Props) => {
const { handleFiles, isImporting } = useImportDocument(collectionId);
const { showToast } = useToasts();
const { t } = useTranslation();
const handleRejection = React.useCallback(() => {
showToast(
t("Document not supported try Markdown, Plain text, HTML, or Word"),
{
type: "error",
}
toast.error(
t("Document not supported try Markdown, Plain text, HTML, or Word")
);
}, [t, showToast]);
}, [t]);
return (
<Dropzone

View File

@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import { useState } from "react";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import { CollectionValidation } from "@shared/validations";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
@@ -11,7 +12,6 @@ import Input from "~/components/Input";
import InputSelect from "~/components/InputSelect";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
collectionId: string;
@@ -30,7 +30,6 @@ const CollectionEdit = ({ collectionId, onSubmit }: Props) => {
direction: "asc" | "desc";
}>(collection.sort);
const [isSaving, setIsSaving] = useState(false);
const { showToast } = useToasts();
const { t } = useTranslation();
const handleSubmit = React.useCallback(
@@ -46,18 +45,14 @@ const CollectionEdit = ({ collectionId, onSubmit }: Props) => {
sort,
});
onSubmit();
showToast(t("The collection was updated"), {
type: "success",
});
toast.success(t("The collection was updated"));
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}
},
[collection, color, icon, name, onSubmit, showToast, sort, t]
[collection, color, icon, name, onSubmit, sort, t]
);
const handleSortChange = (value: string) => {

View File

@@ -3,6 +3,7 @@ import { observable } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { withTranslation, Trans, WithTranslation } from "react-i18next";
import { toast } from "sonner";
import { randomElement } from "@shared/random";
import { CollectionPermission } from "@shared/types";
import { colorPalette } from "@shared/utils/collections";
@@ -66,9 +67,7 @@ class CollectionNew extends React.Component<Props> {
this.props.onSubmit();
history.push(collection.url);
} catch (err) {
this.props.toasts.showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
this.isSaving = false;
}

View File

@@ -2,6 +2,7 @@ import debounce from "lodash/debounce";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import Collection from "~/models/Collection";
import Group from "~/models/Group";
@@ -29,8 +30,7 @@ function AddGroupsToCollection(props: Props) {
useBoolean(false);
const [query, setQuery] = React.useState("");
const { auth, collectionGroupMemberships, groups, policies, toasts } =
useStores();
const { auth, collectionGroupMemberships, groups, policies } = useStores();
const { fetchPage: fetchGroups } = groups;
const { t } = useTranslation();
@@ -55,18 +55,13 @@ function AddGroupsToCollection(props: Props) {
collectionId: collection.id,
groupId: group.id,
});
toasts.showToast(
toast.success(
t("{{ groupName }} was added to the collection", {
groupName: group.name,
}),
{
type: "success",
}
})
);
} catch (err) {
toasts.showToast(t("Could not add user"), {
type: "error",
});
toast.error(t("Could not add user"));
}
};

View File

@@ -1,9 +1,12 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import Collection from "~/models/Collection";
import User from "~/models/User";
import Invite from "~/scenes/Invite";
import Avatar from "~/components/Avatar";
import { AvatarSize } from "~/components/Avatar/Avatar";
import ButtonLink from "~/components/ButtonLink";
import Empty from "~/components/Empty";
import Flex from "~/components/Flex";
@@ -15,7 +18,6 @@ import useBoolean from "~/hooks/useBoolean";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores";
import useThrottledCallback from "~/hooks/useThrottledCallback";
import useToasts from "~/hooks/useToasts";
import MemberListItem from "./components/MemberListItem";
type Props = {
@@ -24,7 +26,6 @@ type Props = {
function AddPeopleToCollection({ collection }: Props) {
const { memberships, users } = useStores();
const { showToast } = useToasts();
const team = useCurrentTeam();
const { t } = useTranslation();
const [inviteModalOpen, setInviteModalOpen, setInviteModalClosed] =
@@ -50,18 +51,16 @@ function AddPeopleToCollection({ collection }: Props) {
collectionId: collection.id,
userId: user.id,
});
showToast(
toast.success(
t("{{ userName }} was added to the collection", {
userName: user.name,
}),
{
type: "success",
icon: <Avatar model={user} size={AvatarSize.Toast} />,
}
);
} catch (err) {
showToast(t("Could not add user"), {
type: "error",
});
toast.error(t("Could not add user"));
}
};

View File

@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import { PlusIcon } from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import { CollectionPermission } from "@shared/types";
import Group from "~/models/Group";
@@ -19,7 +20,6 @@ import Text from "~/components/Text";
import useBoolean from "~/hooks/useBoolean";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import AddGroupsToCollection from "./AddGroupsToCollection";
import AddPeopleToCollection from "./AddPeopleToCollection";
import CollectionGroupMemberListItem from "./components/CollectionGroupMemberListItem";
@@ -40,7 +40,6 @@ function CollectionPermissions({ collectionId }: Props) {
groups,
auth,
} = useStores();
const { showToast } = useToasts();
const collection = collections.get(collectionId);
invariant(collection, "Collection not found");
@@ -60,21 +59,16 @@ function CollectionPermissions({ collectionId }: Props) {
collectionId: collection.id,
userId: user.id,
});
showToast(
toast.success(
t(`{{ userName }} was removed from the collection`, {
userName: user.name,
}),
{
type: "success",
}
})
);
} catch (err) {
showToast(t("Could not remove user"), {
type: "error",
});
toast.error(t("Could not remove user"));
}
},
[memberships, showToast, collection, t]
[memberships, collection, t]
);
const handleUpdateUser = React.useCallback(
@@ -85,21 +79,16 @@ function CollectionPermissions({ collectionId }: Props) {
userId: user.id,
permission,
});
showToast(
toast.success(
t(`{{ userName }} permissions were updated`, {
userName: user.name,
}),
{
type: "success",
}
})
);
} catch (err) {
showToast(t("Could not update user"), {
type: "error",
});
toast.error(t("Could not update user"));
}
},
[memberships, showToast, collection, t]
[memberships, collection, t]
);
const handleRemoveGroup = React.useCallback(
@@ -109,21 +98,16 @@ function CollectionPermissions({ collectionId }: Props) {
collectionId: collection.id,
groupId: group.id,
});
showToast(
toast.success(
t(`The {{ groupName }} group was removed from the collection`, {
groupName: group.name,
}),
{
type: "success",
}
})
);
} catch (err) {
showToast(t("Could not remove group"), {
type: "error",
});
toast.error(t("Could not remove group"));
}
},
[collectionGroupMemberships, showToast, collection, t]
[collectionGroupMemberships, collection, t]
);
const handleUpdateGroup = React.useCallback(
@@ -134,21 +118,16 @@ function CollectionPermissions({ collectionId }: Props) {
groupId: group.id,
permission,
});
showToast(
toast.success(
t(`{{ groupName }} permissions were updated`, {
groupName: group.name,
}),
{
type: "success",
}
})
);
} catch (err) {
showToast(t("Could not update user"), {
type: "error",
});
toast.error(t("Could not update user"));
}
},
[collectionGroupMemberships, showToast, collection, t]
[collectionGroupMemberships, collection, t]
);
const handleChangePermission = React.useCallback(
@@ -157,16 +136,12 @@ function CollectionPermissions({ collectionId }: Props) {
await collection.save({
permission,
});
showToast(t("Default access permissions were updated"), {
type: "success",
});
toast.success(t("Default access permissions were updated"));
} catch (err) {
showToast(t("Could not update permissions"), {
type: "error",
});
toast.error(t("Could not update permissions"));
}
},
[collection, showToast, t]
[collection, t]
);
const fetchOptions = React.useMemo(
@@ -182,16 +157,12 @@ function CollectionPermissions({ collectionId }: Props) {
await collection.save({
sharing: ev.target.checked,
});
showToast(t("Public document sharing permissions were updated"), {
type: "success",
});
toast.success(t("Public document sharing permissions were updated"));
} catch (err) {
showToast(t("Could not update public document sharing"), {
type: "error",
});
toast.error(t("Could not update public document sharing"));
}
},
[collection, showToast, t]
[collection, t]
);
const collectionName = collection.name;

View File

@@ -3,6 +3,7 @@ import { action } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { v4 as uuidv4 } from "uuid";
import { CommentValidation } from "@shared/validations";
import Comment from "~/models/Comment";
@@ -15,7 +16,6 @@ import useCurrentUser from "~/hooks/useCurrentUser";
import useOnClickOutside from "~/hooks/useOnClickOutside";
import usePersistedState from "~/hooks/usePersistedState";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import CommentEditor from "./CommentEditor";
import { Bubble } from "./CommentThreadItem";
@@ -65,7 +65,6 @@ function CommentForm({
const [forceRender, setForceRender] = React.useState(0);
const [inputFocused, setInputFocused] = React.useState(autoFocus);
const { t } = useTranslation();
const { showToast } = useToasts();
const { comments } = useStores();
const user = useCurrentUser();
@@ -106,7 +105,7 @@ function CommentForm({
})
.catch(() => {
comment.isNew = true;
showToast(t("Error creating comment"), { type: "error" });
toast.error(t("Error creating comment"));
});
// optimistically update the comment model
@@ -139,7 +138,7 @@ function CommentForm({
comment.save().catch(() => {
comments.remove(comment.id);
comment.isNew = true;
showToast(t("Error creating comment"), { type: "error" });
toast.error(t("Error creating comment"));
});
// optimistically update the comment model

View File

@@ -4,6 +4,7 @@ import { observer } from "mobx-react";
import { darken } from "polished";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import styled, { css } from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { s } from "@shared/styles";
@@ -17,7 +18,6 @@ import Flex from "~/components/Flex";
import Text from "~/components/Text";
import Time from "~/components/Time";
import useBoolean from "~/hooks/useBoolean";
import useToasts from "~/hooks/useToasts";
import CommentMenu from "~/menus/CommentMenu";
import { hover } from "~/styles";
import CommentEditor from "./CommentEditor";
@@ -85,7 +85,6 @@ function CommentThreadItem({
canReply,
}: Props) {
const { editor } = useDocumentContext();
const { showToast } = useToasts();
const { t } = useTranslation();
const [forceRender, setForceRender] = React.useState(0);
const [data, setData] = React.useState(toJS(comment.data));
@@ -116,7 +115,7 @@ function CommentThreadItem({
});
} catch (error) {
setEditing();
showToast(t("Error updating comment"), { type: "error" });
toast.error(t("Error updating comment"));
}
};

View File

@@ -11,6 +11,7 @@ import {
withRouter,
Redirect,
} from "react-router";
import { toast } from "sonner";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { s } from "@shared/styles";
@@ -176,7 +177,7 @@ class DocumentScene extends React.Component<Props> {
};
onSynced = async () => {
const { toasts, history, location, t } = this.props;
const { history, location, t } = this.props;
const restore = location.state?.restore;
const revisionId = location.state?.revisionId;
const editorRef = this.editor.current;
@@ -191,7 +192,7 @@ class DocumentScene extends React.Component<Props> {
if (response) {
await this.replaceDocument(response.data);
toasts.showToast(t("Document restored"));
toast.success(t("Document restored"));
history.replace(this.props.document.url, history.location.state);
}
};
@@ -316,9 +317,7 @@ class DocumentScene extends React.Component<Props> {
this.props.ui.setActiveDocument(savedDocument);
}
} catch (err) {
this.props.toasts.showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
this.isSaving = false;
this.isPublishing = false;

View File

@@ -3,6 +3,7 @@ import throttle from "lodash/throttle";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { toast } from "sonner";
import { IndexeddbPersistence } from "y-indexeddb";
import * as Y from "yjs";
import MultiplayerExtension from "@shared/editor/extensions/Multiplayer";
@@ -14,7 +15,6 @@ import useIdle from "~/hooks/useIdle";
import useIsMounted from "~/hooks/useIsMounted";
import usePageVisibility from "~/hooks/usePageVisibility";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { AwarenessChangeEvent } from "~/types";
import Logger from "~/utils/Logger";
import { homePath } from "~/utils/routeHelpers";
@@ -51,7 +51,6 @@ function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
const [isLocalSynced, setLocalSynced] = React.useState(false);
const [isRemoteSynced, setRemoteSynced] = React.useState(false);
const [ydoc] = React.useState(() => new Y.Doc());
const { showToast } = useToasts();
const token = auth.collaborationToken;
const isIdle = useIdle();
const isVisible = usePageVisibility();
@@ -180,7 +179,6 @@ function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
};
}, [
history,
showToast,
t,
documentId,
ui,
@@ -251,21 +249,17 @@ function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
React.useEffect(() => {
function onUnhandledError(event: ErrorEvent) {
if (event.message.includes("URIError: URI malformed")) {
showToast(
toast.error(
t(
"Sorry, the last change could not be persisted please reload the page"
),
{
type: "error",
timeout: 0,
}
)
);
}
}
window.addEventListener("error", onUnhandledError);
return () => window.removeEventListener("error", onUnhandledError);
}, [showToast, t]);
}, [t]);
if (!remoteProvider) {
return null;

View File

@@ -6,6 +6,7 @@ import { ExpandedIcon, GlobeIcon, PadlockIcon } from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { Link } from "react-router-dom";
import { toast } from "sonner";
import styled from "styled-components";
import { s } from "@shared/styles";
import { dateLocale, dateToRelative } from "@shared/utils/date";
@@ -23,7 +24,6 @@ import useCurrentTeam from "~/hooks/useCurrentTeam";
import useKeyDown from "~/hooks/useKeyDown";
import usePolicy from "~/hooks/usePolicy";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import useUserLocale from "~/hooks/useUserLocale";
type Props = {
@@ -44,7 +44,6 @@ function SharePopover({
const team = useCurrentTeam();
const { t } = useTranslation();
const { shares, collections } = useStores();
const { showToast } = useToasts();
const [expandedOptions, setExpandedOptions] = React.useState(false);
const [isEditMode, setIsEditMode] = React.useState(false);
const [slugValidationError, setSlugValidationError] = React.useState("");
@@ -100,12 +99,10 @@ function SharePopover({
published: event.currentTarget.checked,
});
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[document.id, shares, showToast]
[document.id, shares]
);
const handleChildDocumentsChange = React.useCallback(
@@ -118,22 +115,18 @@ function SharePopover({
includeChildDocuments: event.currentTarget.checked,
});
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[document.id, shares, showToast]
[document.id, shares]
);
const handleCopied = React.useCallback(() => {
timeout.current = setTimeout(() => {
onRequestClose();
showToast(t("Share link copied"), {
type: "info",
});
toast.message(t("Share link copied"));
}, 250);
}, [t, onRequestClose, showToast]);
}, [t, onRequestClose]);
const handleUrlSlugChange = React.useMemo(
() =>

View File

@@ -2,12 +2,12 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { useHistory } from "react-router-dom";
import { toast } from "sonner";
import Document from "~/models/Document";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { collectionPath, documentPath } from "~/utils/routeHelpers";
type Props = {
@@ -21,7 +21,6 @@ function DocumentDelete({ document, onSubmit }: Props) {
const history = useHistory();
const [isDeleting, setDeleting] = React.useState(false);
const [isArchiving, setArchiving] = React.useState(false);
const { showToast } = useToasts();
const canArchive = !document.isDraft && !document.isArchived;
const collection = document.collectionId
? collections.get(document.collectionId)
@@ -57,14 +56,12 @@ function DocumentDelete({ document, onSubmit }: Props) {
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setDeleting(false);
}
},
[showToast, onSubmit, ui, document, documents, history, collection]
[onSubmit, ui, document, documents, history, collection]
);
const handleArchive = React.useCallback(
@@ -76,14 +73,12 @@ function DocumentDelete({ document, onSubmit }: Props) {
await document.archive();
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setArchiving(false);
}
},
[showToast, onSubmit, document]
[onSubmit, document]
);
return (

View File

@@ -2,6 +2,7 @@ import flatten from "lodash/flatten";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import { ellipsis } from "@shared/styles";
import { NavigationNode } from "@shared/types";
@@ -12,7 +13,6 @@ import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useCollectionTrees from "~/hooks/useCollectionTrees";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { flattenTree } from "~/utils/tree";
type Props = {
@@ -21,7 +21,6 @@ type Props = {
function DocumentMove({ document }: Props) {
const { dialogs } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const collectionTrees = useCollectionTrees();
const [selectedPath, selectPath] = React.useState<NavigationNode | null>(
@@ -51,9 +50,7 @@ function DocumentMove({ document }: Props) {
const move = async () => {
if (!selectedPath) {
showToast(t("Select a location to move"), {
type: "info",
});
toast.message(t("Select a location to move"));
return;
}
@@ -68,15 +65,11 @@ function DocumentMove({ document }: Props) {
await document.move(collectionId);
}
showToast(t("Document moved"), {
type: "success",
});
toast.success(t("Document moved"));
dialogs.closeAllModals();
} catch (err) {
showToast(t("Couldnt move the document, try again?"), {
type: "error",
});
toast.error(t("Couldnt move the document, try again?"));
}
};

View File

@@ -3,13 +3,13 @@ import * as React from "react";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useHistory, useLocation, useRouteMatch } from "react-router-dom";
import { toast } from "sonner";
import CenteredContent from "~/components/CenteredContent";
import Flex from "~/components/Flex";
import PlaceholderDocument from "~/components/PlaceholderDocument";
import useCurrentUser from "~/hooks/useCurrentUser";
import useQuery from "~/hooks/useQuery";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { documentEditPath, documentPath } from "~/utils/routeHelpers";
type Props = {
@@ -25,7 +25,6 @@ function DocumentNew({ template }: Props) {
const match = useRouteMatch<{ id?: string }>();
const { t } = useTranslation();
const { documents, collections } = useStores();
const { showToast } = useToasts();
const id = match.params.id || query.get("collectionId");
useEffect(() => {
@@ -56,9 +55,7 @@ function DocumentNew({ template }: Props) {
location.state
);
} catch (err) {
showToast(t("Couldnt create the document, try again?"), {
type: "error",
});
toast.error(t("Couldnt create the document, try again?"));
history.goBack();
}
}

View File

@@ -2,12 +2,12 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { useHistory } from "react-router-dom";
import { toast } from "sonner";
import Document from "~/models/Document";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
document: Document;
@@ -18,7 +18,6 @@ function DocumentPermanentDelete({ document, onSubmit }: Props) {
const [isDeleting, setIsDeleting] = React.useState(false);
const { t } = useTranslation();
const { documents } = useStores();
const { showToast } = useToasts();
const history = useHistory();
const handleSubmit = React.useCallback(
@@ -30,20 +29,16 @@ function DocumentPermanentDelete({ document, onSubmit }: Props) {
await documents.delete(document, {
permanent: true,
});
showToast(t("Document permanently deleted"), {
type: "success",
});
toast.success(t("Document permanently deleted"));
onSubmit();
history.push("/trash");
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsDeleting(false);
}
},
[document, onSubmit, showToast, t, history, documents]
[document, onSubmit, t, history, documents]
);
return (

View File

@@ -2,6 +2,7 @@ import flatten from "lodash/flatten";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import { ellipsis } from "@shared/styles";
import { NavigationNode } from "@shared/types";
@@ -12,7 +13,6 @@ import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useCollectionTrees from "~/hooks/useCollectionTrees";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { flattenTree } from "~/utils/tree";
type Props = {
@@ -22,7 +22,6 @@ type Props = {
function DocumentPublish({ document }: Props) {
const { dialogs } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const collectionTrees = useCollectionTrees();
const [selectedPath, selectPath] = React.useState<NavigationNode | null>(
@@ -35,9 +34,7 @@ function DocumentPublish({ document }: Props) {
const publish = async () => {
if (!selectedPath) {
showToast(t("Select a location to publish"), {
type: "info",
});
toast.message(t("Select a location to publish"));
return;
}
@@ -54,15 +51,11 @@ function DocumentPublish({ document }: Props) {
document.collectionId = collectionId;
await document.save(undefined, { publish: true });
showToast(t("Document published"), {
type: "success",
});
toast.success(t("Document published"));
dialogs.closeAllModals();
} catch (err) {
showToast(t("Couldnt publish the document, try again?"), {
type: "error",
});
toast.error(t("Couldnt publish the document, try again?"));
}
};

View File

@@ -2,13 +2,13 @@ import { observer } from "mobx-react";
import { useState } from "react";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import { CollectionPermission, NavigationNode } from "@shared/types";
import Collection from "~/models/Collection";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
item:
@@ -33,7 +33,6 @@ type Props = {
function DocumentReparent({ collection, item, onSubmit, onCancel }: Props) {
const [isSaving, setIsSaving] = useState(false);
const { showToast } = useToasts();
const { documents, collections } = useStores();
const { t } = useTranslation();
const prevCollection = collections.get(item.collectionId);
@@ -50,19 +49,15 @@ function DocumentReparent({ collection, item, onSubmit, onCancel }: Props) {
try {
await documents.move(item.id, collection.id);
showToast(t("Document moved"), {
type: "info",
});
toast.message(t("Document moved"));
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}
},
[documents, item.id, collection.id, showToast, t, onSubmit]
[documents, item.id, collection.id, t, onSubmit]
);
return (

View File

@@ -2,11 +2,11 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { useHistory } from "react-router-dom";
import { toast } from "sonner";
import Group from "~/models/Group";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Text from "~/components/Text";
import useToasts from "~/hooks/useToasts";
import { settingsPath } from "~/utils/routeHelpers";
type Props = {
@@ -16,7 +16,6 @@ type Props = {
function GroupDelete({ group, onSubmit }: Props) {
const { t } = useTranslation();
const { showToast } = useToasts();
const history = useHistory();
const [isDeleting, setIsDeleting] = React.useState(false);
@@ -29,9 +28,7 @@ function GroupDelete({ group, onSubmit }: Props) {
history.push(settingsPath("groups"));
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsDeleting(false);
}

View File

@@ -1,12 +1,12 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import Group from "~/models/Group";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Input from "~/components/Input";
import Text from "~/components/Text";
import useToasts from "~/hooks/useToasts";
type Props = {
group: Group;
@@ -14,7 +14,6 @@ type Props = {
};
function GroupEdit({ group, onSubmit }: Props) {
const { showToast } = useToasts();
const { t } = useTranslation();
const [name, setName] = React.useState(group.name);
const [isSaving, setIsSaving] = React.useState(false);
@@ -29,14 +28,12 @@ function GroupEdit({ group, onSubmit }: Props) {
});
onSubmit();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}
},
[group, onSubmit, showToast, name]
[group, onSubmit, name]
);
const handleNameChange = React.useCallback(

View File

@@ -2,9 +2,12 @@ import debounce from "lodash/debounce";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import Group from "~/models/Group";
import User from "~/models/User";
import Invite from "~/scenes/Invite";
import Avatar from "~/components/Avatar";
import { AvatarSize } from "~/components/Avatar/Avatar";
import ButtonLink from "~/components/ButtonLink";
import Empty from "~/components/Empty";
import Flex from "~/components/Flex";
@@ -24,7 +27,7 @@ type Props = {
function AddPeopleToGroup(props: Props) {
const { group } = props;
const { users, auth, groupMemberships, toasts } = useStores();
const { users, auth, groupMemberships } = useStores();
const { t } = useTranslation();
const [query, setQuery] = React.useState("");
@@ -53,18 +56,16 @@ function AddPeopleToGroup(props: Props) {
userId: user.id,
});
toasts.showToast(
toast.success(
t(`{{userName}} was added to the group`, {
userName: user.name,
}),
{
type: "success",
icon: <Avatar model={user} size={AvatarSize.Toast} />,
}
);
} catch (err) {
toasts.showToast(t("Could not add user"), {
type: "error",
});
toast.error(t("Could not add user"));
}
};

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { PlusIcon } from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import Group from "~/models/Group";
import User from "~/models/User";
import Button from "~/components/Button";
@@ -13,7 +14,6 @@ import Subheading from "~/components/Subheading";
import Text from "~/components/Text";
import usePolicy from "~/hooks/usePolicy";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import AddPeopleToGroup from "./AddPeopleToGroup";
import GroupMemberListItem from "./components/GroupMemberListItem";
@@ -24,7 +24,6 @@ type Props = {
function GroupMembers({ group }: Props) {
const [addModalOpen, setAddModalOpen] = React.useState(false);
const { users, groupMemberships } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const can = usePolicy(group);
@@ -38,18 +37,13 @@ function GroupMembers({ group }: Props) {
groupId: group.id,
userId: user.id,
});
showToast(
toast.success(
t(`{{userName}} was removed from the group`, {
userName: user.name,
}),
{
type: "success",
}
})
);
} catch (err) {
showToast(t("Could not remove user"), {
type: "error",
});
toast.error(t("Could not remove user"));
}
};

View File

@@ -1,6 +1,7 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import Group from "~/models/Group";
import GroupMembers from "~/scenes/GroupMembers";
import Button from "~/components/Button";
@@ -9,7 +10,6 @@ import Input from "~/components/Input";
import Modal from "~/components/Modal";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
onSubmit: () => void;
@@ -18,7 +18,6 @@ type Props = {
function GroupNew({ onSubmit }: Props) {
const { groups } = useStores();
const { t } = useTranslation();
const { showToast } = useToasts();
const [name, setName] = React.useState<string | undefined>();
const [isSaving, setIsSaving] = React.useState(false);
const [group, setGroup] = React.useState<Group | undefined>();
@@ -38,9 +37,7 @@ function GroupNew({ onSubmit }: Props) {
await group.save();
setGroup(group);
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}

View File

@@ -3,6 +3,7 @@ import { LinkIcon, CloseIcon } from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { Link } from "react-router-dom";
import { toast } from "sonner";
import styled from "styled-components";
import { s } from "@shared/styles";
import { UserRole } from "@shared/types";
@@ -19,7 +20,6 @@ import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import usePolicy from "~/hooks/usePolicy";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
onSubmit: () => void;
@@ -52,7 +52,6 @@ function Invite({ onSubmit }: Props) {
},
]);
const { users } = useStores();
const { showToast } = useToasts();
const user = useCurrentUser();
const team = useCurrentTeam();
const { t } = useTranslation();
@@ -69,23 +68,17 @@ function Invite({ onSubmit }: Props) {
onSubmit();
if (data.sent.length > 0) {
showToast(t("We sent out your invites!"), {
type: "success",
});
toast.success(t("We sent out your invites!"));
} else {
showToast(t("Those email addresses are already invited"), {
type: "success",
});
toast.message(t("Those email addresses are already invited"));
}
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}
},
[onSubmit, showToast, invites, t, users]
[onSubmit, invites, t, users]
);
const handleChange = React.useCallback((ev, index) => {
@@ -98,13 +91,10 @@ function Invite({ onSubmit }: Props) {
const handleAdd = React.useCallback(() => {
if (invites.length >= UserValidation.maxInvitesPerRequest) {
showToast(
toast.message(
t("Sorry, you can only send {{MAX_INVITES}} invites at a time", {
MAX_INVITES: UserValidation.maxInvitesPerRequest,
}),
{
type: "warning",
}
})
);
}
@@ -117,7 +107,7 @@ function Invite({ onSubmit }: Props) {
});
return newInvites;
});
}, [showToast, invites, t]);
}, [invites, t]);
const handleRemove = React.useCallback(
(ev: React.SyntheticEvent, index: number) => {
@@ -133,10 +123,8 @@ function Invite({ onSubmit }: Props) {
const handleCopy = React.useCallback(() => {
setLinkCopied(true);
showToast(t("Share link copied"), {
type: "success",
});
}, [showToast, t]);
toast.success(t("Share link copied"));
}, [t]);
const handleRoleChange = React.useCallback(
(role: UserRole, index: number) => {

View File

@@ -5,6 +5,7 @@ import { TeamIcon } from "outline-icons";
import { useRef, useState } from "react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import { ThemeProvider, useTheme } from "styled-components";
import { buildDarkTheme, buildLightTheme } from "@shared/styles/theme";
import { CustomTheme, TeamPreference } from "@shared/types";
@@ -21,7 +22,6 @@ import Text from "~/components/Text";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import usePolicy from "~/hooks/usePolicy";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import isCloudHosted from "~/utils/isCloudHosted";
import TeamDelete from "../TeamDelete";
import ImageInput from "./components/ImageInput";
@@ -29,7 +29,6 @@ import SettingRow from "./components/SettingRow";
function Details() {
const { auth, dialogs, ui } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const team = useCurrentTeam();
const theme = useTheme();
@@ -76,13 +75,9 @@ function Details() {
customTheme,
},
});
showToast(t("Settings saved"), {
type: "success",
});
toast.success(t("Settings saved"));
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[
@@ -93,7 +88,6 @@ function Details() {
team.preferences,
publicBranding,
customTheme,
showToast,
t,
]
);
@@ -116,16 +110,14 @@ function Details() {
await auth.updateTeam({
avatarUrl,
});
showToast(t("Logo updated"), {
type: "success",
});
toast.success(t("Logo updated"));
};
const handleAvatarError = React.useCallback(
(error: string | null | undefined) => {
showToast(error || t("Unable to upload new logo"));
toast.error(error || t("Unable to upload new logo"));
},
[showToast, t]
[t]
);
const showDeleteWorkspace = () => {

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { BeakerIcon } from "outline-icons";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import { TeamPreference } from "@shared/types";
import Heading from "~/components/Heading";
import Scene from "~/components/Scene";
@@ -9,14 +10,12 @@ import Switch from "~/components/Switch";
import Text from "~/components/Text";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import SettingRow from "./components/SettingRow";
function Features() {
const { auth } = useStores();
const team = useCurrentTeam();
const { t } = useTranslation();
const { showToast } = useToasts();
const handlePreferenceChange =
(inverted = false) =>
@@ -27,9 +26,7 @@ function Features() {
};
await auth.updateTeam({ preferences });
showToast(t("Settings saved"), {
type: "success",
});
toast.success(t("Settings saved"));
};
return (

View File

@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useForm } from "react-hook-form";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import { IntegrationType, IntegrationService } from "@shared/types";
import Integration from "~/models/Integration";
import Button from "~/components/Button";
@@ -12,7 +13,6 @@ import Input from "~/components/Input";
import Scene from "~/components/Scene";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import SettingRow from "./components/SettingRow";
type FormData = {
@@ -22,7 +22,6 @@ type FormData = {
function GoogleAnalytics() {
const { integrations } = useStores();
const { t } = useTranslation();
const { showToast } = useToasts();
const integration = find(integrations.orderedData, {
type: IntegrationType.Analytics,
@@ -67,16 +66,12 @@ function GoogleAnalytics() {
await integration?.delete();
}
showToast(t("Settings saved"), {
type: "success",
});
toast.success(t("Settings saved"));
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[integrations, integration, t, showToast]
[integrations, integration, t]
);
return (

View File

@@ -13,6 +13,7 @@ import {
} from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import { NotificationEventType } from "@shared/types";
import Flex from "~/components/Flex";
import Heading from "~/components/Heading";
@@ -23,12 +24,10 @@ import Switch from "~/components/Switch";
import Text from "~/components/Text";
import env from "~/env";
import useCurrentUser from "~/hooks/useCurrentUser";
import useToasts from "~/hooks/useToasts";
import isCloudHosted from "~/utils/isCloudHosted";
import SettingRow from "./components/SettingRow";
function Notifications() {
const { showToast } = useToasts();
const user = useCurrentUser();
const { t } = useTranslation();
@@ -106,9 +105,7 @@ function Notifications() {
];
const showSuccessMessage = debounce(() => {
showToast(t("Notifications saved"), {
type: "success",
});
toast.success(t("Notifications saved"));
}, 500);
const handleChange = React.useCallback(

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { SettingsIcon } from "outline-icons";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import { languageOptions } from "@shared/i18n";
import { TeamPreference, UserPreference } from "@shared/types";
import Button from "~/components/Button";
@@ -13,13 +14,11 @@ import Text from "~/components/Text";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import UserDelete from "../UserDelete";
import SettingRow from "./components/SettingRow";
function Preferences() {
const { t } = useTranslation();
const { showToast } = useToasts();
const { dialogs, auth } = useStores();
const user = useCurrentUser();
const team = useCurrentTeam();
@@ -33,16 +32,12 @@ function Preferences() {
};
await auth.updateUser({ preferences });
showToast(t("Preferences saved"), {
type: "success",
});
toast.success(t("Preferences saved"));
};
const handleLanguageChange = async (language: string) => {
await auth.updateUser({ language });
showToast(t("Preferences saved"), {
type: "success",
});
toast.success(t("Preferences saved"));
};
const showDeleteAccount = () => {

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { ProfileIcon } from "outline-icons";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import Button from "~/components/Button";
import Heading from "~/components/Heading";
import Input from "~/components/Input";
@@ -9,7 +10,6 @@ import Scene from "~/components/Scene";
import Text from "~/components/Text";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import ImageInput from "./components/ImageInput";
import SettingRow from "./components/SettingRow";
@@ -18,7 +18,6 @@ const Profile = () => {
const user = useCurrentUser();
const form = React.useRef<HTMLFormElement>(null);
const [name, setName] = React.useState<string>(user.name || "");
const { showToast } = useToasts();
const { t } = useTranslation();
const handleSubmit = async (ev: React.SyntheticEvent) => {
@@ -28,13 +27,9 @@ const Profile = () => {
await auth.updateUser({
name,
});
showToast(t("Profile saved"), {
type: "success",
});
toast.success(t("Profile saved"));
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
};
@@ -46,15 +41,11 @@ const Profile = () => {
await auth.updateUser({
avatarUrl,
});
showToast(t("Profile picture updated"), {
type: "success",
});
toast.success(t("Profile picture updated"));
};
const handleAvatarError = (error: string | null | undefined) => {
showToast(error || t("Unable to upload new profile picture"), {
type: "error",
});
toast.error(error || t("Unable to upload new profile picture"));
};
const isValid = form.current?.checkValidity();

View File

@@ -4,6 +4,7 @@ import { CheckboxIcon, EmailIcon, PadlockIcon } from "outline-icons";
import { useState } from "react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import { useTheme } from "styled-components";
import { TeamPreference } from "@shared/types";
import ConfirmationDialog from "~/components/ConfirmationDialog";
@@ -18,7 +19,6 @@ import env from "~/env";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useRequest from "~/hooks/useRequest";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import isCloudHosted from "~/utils/isCloudHosted";
import DomainManagement from "./components/DomainManagement";
import SettingRow from "./components/SettingRow";
@@ -27,7 +27,6 @@ function Security() {
const { auth, authenticationProviders, dialogs } = useStores();
const team = useCurrentTeam();
const { t } = useTranslation();
const { showToast } = useToasts();
const theme = useTheme();
const [data, setData] = useState({
sharing: team.sharing,
@@ -53,11 +52,9 @@ function Security() {
const showSuccessMessage = React.useMemo(
() =>
debounce(() => {
showToast(t("Settings saved"), {
type: "success",
});
toast.success(t("Settings saved"));
}, 250),
[showToast, t]
[t]
);
const saveData = React.useCallback(
@@ -67,12 +64,10 @@ function Security() {
await auth.updateTeam(newData);
showSuccessMessage();
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[auth, showSuccessMessage, showToast]
[auth, showSuccessMessage]
);
const handleChange = React.useCallback(

View File

@@ -4,6 +4,7 @@ import { BuildingBlocksIcon } from "outline-icons";
import * as React from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { IntegrationService, IntegrationType } from "@shared/types";
import Integration from "~/models/Integration";
import Button from "~/components/Button";
@@ -11,7 +12,6 @@ import Heading from "~/components/Heading";
import Input from "~/components/Input";
import Scene from "~/components/Scene";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import SettingRow from "./components/SettingRow";
type FormData = {
@@ -22,7 +22,6 @@ type FormData = {
function SelfHosted() {
const { integrations } = useStores();
const { t } = useTranslation();
const { showToast } = useToasts();
const integrationDiagrams = find(integrations.orderedData, {
type: IntegrationType.Embed,
@@ -89,16 +88,12 @@ function SelfHosted() {
await integrationGrist?.delete();
}
showToast(t("Settings saved"), {
type: "success",
});
toast.success(t("Settings saved"));
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
},
[integrations, integrationDiagrams, integrationGrist, t, showToast]
[integrations, integrationDiagrams, integrationGrist, t]
);
return (

View File

@@ -1,12 +1,12 @@
import { CopyIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import ApiKey from "~/models/ApiKey";
import Button from "~/components/Button";
import CopyToClipboard from "~/components/CopyToClipboard";
import Flex from "~/components/Flex";
import ListItem from "~/components/List/Item";
import useToasts from "~/hooks/useToasts";
import ApiKeyMenu from "~/menus/ApiKeyMenu";
type Props = {
@@ -15,7 +15,6 @@ type Props = {
const ApiKeyListItem = ({ apiKey }: Props) => {
const { t } = useTranslation();
const { showToast } = useToasts();
const [linkCopied, setLinkCopied] = React.useState<boolean>(false);
React.useEffect(() => {
@@ -28,10 +27,8 @@ const ApiKeyListItem = ({ apiKey }: Props) => {
const handleCopy = React.useCallback(() => {
setLinkCopied(true);
showToast(t("API token copied to clipboard"), {
type: "success",
});
}, [showToast, t]);
toast.message(t("API token copied to clipboard"));
}, [t]);
return (
<ListItem

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { CloseIcon } from "outline-icons";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import Button from "~/components/Button";
import Fade from "~/components/Fade";
@@ -11,7 +12,6 @@ import NudeButton from "~/components/NudeButton";
import Tooltip from "~/components/Tooltip";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import SettingRow from "./SettingRow";
type Props = {
@@ -22,7 +22,6 @@ function DomainManagement({ onSuccess }: Props) {
const { auth } = useStores();
const team = useCurrentTeam();
const { t } = useTranslation();
const { showToast } = useToasts();
const [allowedDomains, setAllowedDomains] = React.useState([
...(team.allowedDomains ?? []),
@@ -43,11 +42,9 @@ function DomainManagement({ onSuccess }: Props) {
setExistingDomainsTouched(false);
updateLastKnownDomainCount(allowedDomains.length);
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
}, [auth, allowedDomains, onSuccess, showToast]);
}, [auth, allowedDomains, onSuccess]);
const handleRemoveDomain = async (index: number) => {
const newDomains = allowedDomains.filter((_, i) => index !== i);

View File

@@ -3,13 +3,13 @@ import { NewDocumentIcon } from "outline-icons";
import * as React from "react";
import Dropzone from "react-dropzone";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import styled from "styled-components";
import { s } from "@shared/styles";
import { AttachmentPreset } from "@shared/types";
import Flex from "~/components/Flex";
import LoadingIndicator from "~/components/LoadingIndicator";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import { uploadFile } from "~/utils/files";
type Props = {
@@ -23,15 +23,12 @@ type Props = {
function DropToImport({ disabled, onSubmit, children, format }: Props) {
const { t } = useTranslation();
const { collections } = useStores();
const { showToast } = useToasts();
const [isImporting, setImporting] = React.useState(false);
const handleFiles = React.useCallback(
async (files) => {
if (files.length > 1) {
showToast(t("Please choose a single file to import"), {
type: "error",
});
toast.error(t("Please choose a single file to import"));
return;
}
const file = files[0];
@@ -45,27 +42,21 @@ function DropToImport({ disabled, onSubmit, children, format }: Props) {
});
await collections.import(attachment.id, format);
onSubmit();
showToast(
t("Your import is being processed, you can safely leave this page"),
{
type: "success",
timeout: 6000,
}
toast.success(
t("Your import is being processed, you can safely leave this page")
);
} catch (err) {
showToast(err.message);
toast.error(err.message);
} finally {
setImporting(false);
}
},
[t, onSubmit, collections, format, showToast]
[t, onSubmit, collections, format]
);
const handleRejection = React.useCallback(() => {
showToast(t("File not supported please upload a valid ZIP file"), {
type: "error",
});
}, [t, showToast]);
toast.error(t("File not supported please upload a valid ZIP file"));
}, [t]);
if (disabled) {
return children;

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import { ArchiveIcon, DoneIcon, WarningIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { useTheme } from "styled-components";
import {
FileOperationFormat,
@@ -16,7 +17,6 @@ import Spinner from "~/components/Spinner";
import Time from "~/components/Time";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import FileOperationMenu from "~/menus/FileOperationMenu";
type Props = {
@@ -28,7 +28,6 @@ const FileOperationListItem = ({ fileOperation }: Props) => {
const user = useCurrentUser();
const theme = useTheme();
const { dialogs, fileOperations } = useStores();
const { showToast } = useToasts();
const stateMapping = {
[FileOperationState.Creating]: t("Processing"),
@@ -65,16 +64,14 @@ const FileOperationListItem = ({ fileOperation }: Props) => {
await fileOperations.delete(fileOperation);
if (fileOperation.type === FileOperationType.Import) {
showToast(t("Import deleted"));
toast.success(t("Import deleted"));
} else {
showToast(t("Export deleted"));
toast.success(t("Export deleted"));
}
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
}
}, [fileOperation, fileOperations, showToast, t]);
}, [fileOperation, fileOperations, t]);
const handleConfirmDelete = React.useCallback(async () => {
dialogs.openModal({

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useForm } from "react-hook-form";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Input from "~/components/Input";
@@ -9,7 +10,6 @@ import Text from "~/components/Text";
import env from "~/env";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type FormData = {
code: string;
@@ -22,7 +22,6 @@ type Props = {
function TeamDelete({ onSubmit }: Props) {
const [isWaitingCode, setWaitingCode] = React.useState(false);
const { auth } = useStores();
const { showToast } = useToasts();
const team = useCurrentTeam();
const { t } = useTranslation();
const {
@@ -39,12 +38,10 @@ function TeamDelete({ onSubmit }: Props) {
await auth.requestDeleteTeam();
setWaitingCode(true);
} catch (error) {
showToast(error.message, {
type: "error",
});
toast.error(error.message);
}
},
[auth, showToast]
[auth]
);
const handleSubmit = React.useCallback(
@@ -54,12 +51,10 @@ function TeamDelete({ onSubmit }: Props) {
await auth.logout();
onSubmit();
} catch (error) {
showToast(error.message, {
type: "error",
});
toast.error(error.message);
}
},
[auth, onSubmit, showToast]
[auth, onSubmit]
);
const inputProps = register("code", {

View File

@@ -1,6 +1,7 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import User from "~/models/User";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
@@ -8,7 +9,6 @@ import Input from "~/components/Input";
import Notice from "~/components/Notice";
import Text from "~/components/Text";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type Props = {
user: User;
@@ -17,7 +17,6 @@ type Props = {
function TeamNew({ user }: Props) {
const { auth } = useStores();
const { t } = useTranslation();
const { showToast } = useToasts();
const [name, setName] = React.useState("");
const [isSaving, setIsSaving] = React.useState(false);
@@ -32,9 +31,7 @@ function TeamNew({ user }: Props) {
});
}
} catch (err) {
showToast(err.message, {
type: "error",
});
toast.error(err.message);
} finally {
setIsSaving(false);
}

View File

@@ -2,13 +2,13 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useForm } from "react-hook-form";
import { useTranslation, Trans } from "react-i18next";
import { toast } from "sonner";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import Input from "~/components/Input";
import Text from "~/components/Text";
import env from "~/env";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
type FormData = {
code: string;
@@ -17,7 +17,6 @@ type FormData = {
function UserDelete() {
const [isWaitingCode, setWaitingCode] = React.useState(false);
const { auth } = useStores();
const { showToast } = useToasts();
const { t } = useTranslation();
const {
register,
@@ -32,13 +31,11 @@ function UserDelete() {
try {
await auth.requestDeleteUser();
setWaitingCode(true);
} catch (error) {
showToast(error.message, {
type: "error",
});
} catch (err) {
toast.error(err.message);
}
},
[auth, showToast]
[auth]
);
const handleSubmit = React.useCallback(
@@ -46,13 +43,11 @@ function UserDelete() {
try {
await auth.deleteUser(data);
await auth.logout();
} catch (error) {
showToast(error.message, {
type: "error",
});
} catch (err) {
toast.error(err.message);
}
},
[auth, showToast]
[auth]
);
const inputProps = register("code", {