Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2174: Replace unmaintained react-toast-notifications (and use one style for all toasts) #2836

Merged
merged 18 commits into from
Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions src/auth/ScopeSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { StatusCodes } from "http-status-codes";
import { getLinkedApiClient } from "@/services/apiClient";
import { isAxiosError } from "@/errors";
import reportError from "@/telemetry/reportError";
import useNotifications from "@/hooks/useNotifications";
import notify from "@/utils/notify";
import ConnectedFieldTemplate from "@/components/form/ConnectedFieldTemplate";
import { useGetAuthQuery } from "@/services/api";

Expand Down Expand Up @@ -56,7 +56,6 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({
title,
description,
}) => {
const notify = useNotifications();
const { refetch: refetchAuth } = useGetAuthQuery();

const submit = useCallback(
Expand All @@ -68,15 +67,14 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({
await (await getLinkedApiClient()).patch("/api/settings/", values);
} catch (error) {
if (!isAxiosError(error)) {
notify.error("Error updating account alias", {
error,
});
notify.error({ message: "Error updating account alias", error });
Copy link
Contributor Author

@fregante fregante Feb 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API improvement: Either call it with a plain string or provide a regular Notification object.

Pros:

  • no awkward { error } wrap
  • simpler types
  • safer: no unknown as the first parameter of notify.error just to allow notify.error(new Error())

Cons:

  • 8 extra characters 😌 message: if you need to include the error

Copy link
Contributor

@twschiller twschiller Mar 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 extra characters 😌 message: if you need to include the error

I'm not sure we have the budget for the extra storage

return;
}

switch (error.response.status) {
case StatusCodes.UNAUTHORIZED: {
notify.error("Could not authenticate with PixieBrix", {
notify.error({
message: "Could not authenticate with PixieBrix",
error,
});
return;
Expand All @@ -89,17 +87,15 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({

default: {
reportError(error);
notify.error("Error updating account alias", {
error,
});
notify.error({ message: "Error updating account alias", error });
return;
}
}
}

refetchAuth();
},
[notify]
[]
);

return (
Expand Down
18 changes: 5 additions & 13 deletions src/background/contextMenus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import browser, { Menus, Tabs } from "webextension-polyfill";
import { getErrorMessage, hasCancelRootCause } from "@/errors";
import reportError from "@/telemetry/reportError";
import { noop } from "lodash";
import {
handleMenuAction,
showNotification,
} from "@/contentScript/messenger/api";
import { handleMenuAction, notify } from "@/contentScript/messenger/api";
import { ensureContentScript } from "@/background/util";
import { reportEvent } from "@/telemetry/events";
import { UUID, IExtension, ResolvedExtension } from "@/core";
Expand Down Expand Up @@ -95,21 +92,16 @@ async function dispatchMenu(
extensionId: info.menuItemId.slice(MENU_PREFIX.length) as UUID,
args: info,
});
void showNotification(target, {
message: "Ran content menu item action",
type: "success",
});
notify.success(target, "Ran content menu item action");
} catch (error) {
if (hasCancelRootCause(error)) {
void showNotification(target, {
message: "The action was cancelled",
});
notify.info(target, "The action was cancelled");
} else {
const message = `Error handling context menu action: ${getErrorMessage(
error
)}`;
reportError(new Error(message));
void showNotification(target, { message, type: "error" });
reportError(error);
Copy link
Contributor Author

@fregante fregante Feb 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to report the original error here. The stack trace will point to this block anyway, but its origin will be better defined.

Here it's called explicitly because the messaging API does not automatically serialize errors, especially deep inside other objects.

notify.error(target, { message, reportError: false });
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/blocks/effects/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { Effect } from "@/types";
import { BlockArg, Schema } from "@/core";
import { propertiesToSchema } from "@/validators/generic";
import { showNotification } from "@/contentScript/notify";
import { showNotification } from "@/utils/notify";

export class AlertEffect extends Effect {
constructor() {
Expand Down
2 changes: 1 addition & 1 deletion src/blocks/renderers/customForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import JsonSchemaForm from "@rjsf/bootstrap-4";
import { JsonObject } from "type-fest";
import { dataStore } from "@/background/messenger/api";
import reportError from "@/telemetry/reportError";
import { notifyResult } from "@/contentScript/notify";
import { notifyResult } from "@/utils/notify";

import custom from "@/blocks/renderers/customForm.css?loadAsUrl";
import BootstrapStylesheet from "./BootstrapStylesheet";
Expand Down
2 changes: 1 addition & 1 deletion src/contentScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { markReady, updateTabInfo } from "@/contentScript/context";
import { whoAmI, initTelemetry } from "@/background/messenger/api";
import { ENSURE_CONTENT_SCRIPT_READY } from "@/messaging/constants";
import { addListenerForUpdateSelectedElement } from "@/devTools/getSelectedElement";
import { initToaster } from "@/contentScript/notify";
import { initToaster } from "@/utils/notify";
import { isConnectionError } from "@/errors";
import { showConnectionLost } from "@/contentScript/connection";

Expand Down
5 changes: 2 additions & 3 deletions src/contentScript/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { hideNotification, showNotification } from "@/contentScript/notify";
import notify, { hideNotification } from "@/utils/notify";

const id = "connection-lost";

export function showConnectionLost(): void {
showNotification({
notify.error({
id,
message: "Connection to PixieBrix lost. Please reload the page",
type: "error",
duration: Number.POSITIVE_INFINITY,
});
}
Expand Down
7 changes: 6 additions & 1 deletion src/contentScript/messenger/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ export const disableOverlay = getMethod("DISABLE_OVERLAY");
export const getInstalledExtensionPointIds = getMethod("INSTALLED_EXTENSIONS");
export const checkAvailable = getMethod("CHECK_AVAILABLE");
export const handleNavigate = getNotifier("HANDLE_NAVIGATE");
export const showNotification = getMethod("SHOW_NOTIFICATION");
export const runBrick = getMethod("RUN_BRICK");
export const cancelSelect = getMethod("CANCEL_SELECT_ELEMENT");
export const selectElement = getMethod("SELECT_ELEMENT");

export const runRendererPipeline = getMethod("RUN_RENDERER_PIPELINE");
export const runEffectPipeline = getMethod("RUN_EFFECT_PIPELINE");
export const runMapArgs = getMethod("RUN_MAP_ARGS");

export const notify = {
info: getNotifier("NOTIFY_INFO"),
error: getNotifier("NOTIFY_ERROR"),
success: getNotifier("NOTIFY_SUCCESS"),
};
12 changes: 9 additions & 3 deletions src/contentScript/messenger/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import {
resetTab,
} from "@/contentScript/devTools";
import { checkAvailable } from "@/blocks/available";
import { showNotification } from "@/contentScript/notify";
import notify from "@/utils/notify";
import { runBrick } from "@/contentScript/executor";
import {
cancelSelect,
Expand Down Expand Up @@ -112,14 +112,17 @@ declare global {
INSTALLED_EXTENSIONS: typeof getInstalledIds;
CHECK_AVAILABLE: typeof checkAvailable;
HANDLE_NAVIGATE: typeof handleNavigate;
SHOW_NOTIFICATION: typeof showNotification;
RUN_BRICK: typeof runBrick;
CANCEL_SELECT_ELEMENT: typeof cancelSelect;
SELECT_ELEMENT: typeof selectElement;

RUN_RENDERER_PIPELINE: typeof runRendererPipeline;
RUN_EFFECT_PIPELINE: typeof runEffectPipeline;
RUN_MAP_ARGS: typeof runMapArgs;

NOTIFY_INFO: typeof notify.info;
NOTIFY_ERROR: typeof notify.error;
NOTIFY_SUCCESS: typeof notify.success;
}
}

Expand Down Expand Up @@ -163,7 +166,6 @@ export default function registerMessenger(): void {
INSTALLED_EXTENSIONS: getInstalledIds,
CHECK_AVAILABLE: checkAvailable,
HANDLE_NAVIGATE: handleNavigate,
SHOW_NOTIFICATION: showNotification,

RUN_BRICK: runBrick,
CANCEL_SELECT_ELEMENT: cancelSelect,
Expand All @@ -172,5 +174,9 @@ export default function registerMessenger(): void {
RUN_RENDERER_PIPELINE: runRendererPipeline,
RUN_EFFECT_PIPELINE: runEffectPipeline,
RUN_MAP_ARGS: runMapArgs,

NOTIFY_INFO: notify.info,
NOTIFY_ERROR: notify.error,
NOTIFY_SUCCESS: notify.success,
});
}
13 changes: 5 additions & 8 deletions src/contrib/google/sheets/FileWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ensureAuth } from "@/contrib/google/auth";
import { isOptionsPage } from "webext-detect-page";
import browser from "webextension-polyfill";
import { Form, InputGroup } from "react-bootstrap";
import useNotifications from "@/hooks/useNotifications";
import notify from "@/utils/notify";
import { getErrorMessage } from "@/errors";
import AsyncButton from "@/components/AsyncButton";
import { Expression } from "@/core";
Expand All @@ -46,8 +46,6 @@ type FileWidgetProps = {
};

const FileWidget: React.FC<FileWidgetProps> = ({ doc, onSelect, ...props }) => {
const notify = useNotifications();

const [field, , helpers] = useField<string | Expression>(props);
const [sheetError, setSheetError] = useState(null);

Expand Down Expand Up @@ -91,9 +89,7 @@ const FileWidget: React.FC<FileWidgetProps> = ({ doc, onSelect, ...props }) => {
if (!isMounted()) return;
onSelect(null);
setSheetError(error);
notify.error("Error retrieving sheet information", {
error,
});
notify.error({ message: "Error retrieving sheet information", error });
}
},
[doc?.id, field.value, onSelect, setSheetError]
Expand Down Expand Up @@ -146,11 +142,12 @@ const FileWidget: React.FC<FileWidgetProps> = ({ doc, onSelect, ...props }) => {
.build();
picker.setVisible(true);
} catch (error) {
notify.error(`Error loading file picker: ${getErrorMessage(error)}`, {
notify.error({
message: `Error loading file picker: ${getErrorMessage(error)}`,
error,
});
}
}, [notify, helpers, onSelect]);
}, [helpers, onSelect]);

return isExpression(field.value) ? (
<WorkshopMessageWidget />
Expand Down
26 changes: 7 additions & 19 deletions src/contrib/pipedrive/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Effect } from "@/types";
import { proxyService } from "@/background/messenger/api";
import { propertiesToSchema } from "@/validators/generic";
import { BlockArg } from "@/core";
import { showNotification } from "@/contentScript/notify";
import notify from "@/utils/notify";

export class AddOrganization extends Effect {
// https://developers.pipedrive.com/docs/api/v1/#!/Organizations/post_organizations
Expand Down Expand Up @@ -62,7 +62,7 @@ export class AddOrganization extends Effect {
});

if (data.items.length > 0) {
showNotification({ message: `Organization already exists for ${name}` });
notify.info(`Organization already exists for ${name}`);
return;
}

Expand All @@ -72,15 +72,9 @@ export class AddOrganization extends Effect {
method: "post",
data: { name, owner_id },
});
showNotification({
message: `Added ${name} to Pipedrive`,
type: "success",
});
notify.success(`Added ${name} to Pipedrive`);
} catch {
showNotification({
message: `Error adding ${name} to Pipedrive`,
type: "error",
});
notify.error(`Error adding ${name} to Pipedrive`);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @twschiller suggested in https://github.com/pixiebrix/pixiebrix-app/pull/1252, errors are automatically reported. This was not the case with the previous showNotification implementation so let me know if I should set report: false to some of these.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should actually be logger statements and BusinessErrors. Will change these

}
}
}
Expand Down Expand Up @@ -140,7 +134,7 @@ export class AddPerson extends Effect {
});

if (data.items.length > 0) {
showNotification({ message: `Person record already exists for ${name}` });
notify.info({ message: `Person record already exists for ${name}` });
return;
}

Expand All @@ -155,15 +149,9 @@ export class AddPerson extends Effect {
phone: phone ? [phone] : undefined,
},
});
showNotification({
message: `Added ${name} to Pipedrive`,
type: "success",
});
notify.success(`Added ${name} to Pipedrive`);
} catch {
showNotification({
message: `Error adding ${name} to Pipedrive`,
type: "error",
});
notify.error(`Error adding ${name} to Pipedrive`);
}
}
}
8 changes: 3 additions & 5 deletions src/devTools/editor/fields/DatabaseCreateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
} from "@/services/api";
import SelectWidget from "@/components/form/widgets/SelectWidget";
import DatabaseGroupSelect from "./DatabaseGroupSelect";
import useNotifications from "@/hooks/useNotifications";
import notify from "@/utils/notify";
import { Organization, UserRole } from "@/types/contract";
import { UUID } from "@/core";
import { validateUUID } from "@/types/helpers";
Expand Down Expand Up @@ -94,16 +94,14 @@ const DatabaseCreateModal: React.FC<DatabaseCreateModalProps> = ({

const [addDatabaseToGroup] = useAddDatabaseToGroupMutation();

const notify = useNotifications();

const onSave = async ({ name, organizationId, groupId }: DatabaseConfig) => {
const createDatabaseResult = await createDatabase({
name,
organizationId,
});

if ("error" in createDatabaseResult) {
notify.error(createDatabaseResult.error);
notify.error({ error: createDatabaseResult.error });
onClose();
return;
}
Expand All @@ -117,7 +115,7 @@ const DatabaseCreateModal: React.FC<DatabaseCreateModalProps> = ({
});

if ("error" in addToGroupResult) {
notify.error(addToGroupResult.error);
notify.error({ error: addToGroupResult.error });
onClose();
return;
}
Expand Down
10 changes: 5 additions & 5 deletions src/devTools/editor/fields/SelectorSelectorWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import styles from "./SelectorSelectorWidget.module.scss";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import useNotifications from "@/hooks/useNotifications";
import notify from "@/utils/notify";
import { compact, isEmpty, sortBy, uniqBy } from "lodash";
import { getErrorMessage } from "@/errors";
import { Button, InputGroup } from "react-bootstrap";
Expand Down Expand Up @@ -105,7 +105,6 @@ const SelectorSelectorWidget: React.FC<SelectorSelectorProps> = ({
const defaultSort = selectMode === "element";
const sort = rawSort ?? defaultSort;

const notify = useNotifications();
const [element, setElement] = useState(initialElement);
const [isSelecting, setSelecting] = useState(false);

Expand Down Expand Up @@ -155,7 +154,8 @@ const SelectorSelectorWidget: React.FC<SelectorSelectorProps> = ({
});

if (isEmpty(selected)) {
notify.error("Unknown error selecting element", {
notify.error({
message: "Unknown error selecting element",
error: new Error("selectElement returned empty object"),
});
return;
Expand All @@ -172,7 +172,8 @@ const SelectorSelectorWidget: React.FC<SelectorSelectorProps> = ({
console.debug("Setting selector", { selected, firstSelector });
setValue(firstSelector);
} catch (error) {
notify.error(`Error selecting element: ${getErrorMessage(error)}`, {
notify.error({
message: `Error selecting element: ${getErrorMessage(error)}`,
error,
});
} finally {
Expand All @@ -181,7 +182,6 @@ const SelectorSelectorWidget: React.FC<SelectorSelectorProps> = ({
}, [
sort,
framework,
notify,
setSelecting,
traverseUp,
selectMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { uuidv4 } from "@/types/helpers";
import { waitForEffect } from "@/tests/testHelpers";
import { anonAuth } from "@/hooks/auth";

jest.mock("@/hooks/useNotifications");
jest.mock("@/utils/notify");
jest.mock("./useSavingWizard");

jest.mock("@/services/api", () => ({
Expand Down
Loading