diff --git a/app/actions/definitions/developer.tsx b/app/actions/definitions/developer.tsx
index 290202ee9..f0c5e950e 100644
--- a/app/actions/definitions/developer.tsx
+++ b/app/actions/definitions/developer.tsx
@@ -86,19 +86,14 @@ export const clearIndexedDB = createAction({
});
export const createTestUsers = createAction({
- name: "Create test users",
+ name: "Create 10 test users",
icon: ,
section: DeveloperSection,
visible: () => env.ENVIRONMENT === "development",
perform: async () => {
const count = 10;
-
- try {
- await client.post("/developer.create_test_users", { count });
- toast.message(`${count} test users created`);
- } catch (err) {
- toast.error(err.message);
- }
+ await client.post("/developer.create_test_users", { count });
+ toast.message(`${count} test users created`);
},
});
diff --git a/app/actions/definitions/documents.tsx b/app/actions/definitions/documents.tsx
index 61407ef2c..c52e625d1 100644
--- a/app/actions/definitions/documents.tsx
+++ b/app/actions/definitions/documents.tsx
@@ -251,17 +251,13 @@ export const unpublishDocument = createAction({
return;
}
- try {
- await document.unpublish();
+ await document.unpublish();
- toast.success(
- t("Unpublished {{ documentName }}", {
- documentName: document.noun,
- })
- );
- } catch (err) {
- toast.error(err.message);
- }
+ toast.success(
+ t("Unpublished {{ documentName }}", {
+ documentName: document.noun,
+ })
+ );
},
});
@@ -288,9 +284,7 @@ export const subscribeDocument = createAction({
}
const document = stores.documents.get(activeDocumentId);
-
await document?.subscribe();
-
toast.success(t("Subscribed to document notifications"));
},
});
@@ -540,17 +534,13 @@ export const pinDocumentToCollection = createAction({
return;
}
- try {
- const document = stores.documents.get(activeDocumentId);
- await document?.pin(document.collectionId);
+ const document = stores.documents.get(activeDocumentId);
+ await document?.pin(document.collectionId);
- const collection = stores.collections.get(activeCollectionId);
+ const collection = stores.collections.get(activeCollectionId);
- if (!collection || !location.pathname.startsWith(collection?.url)) {
- toast.success(t("Pinned to collection"));
- }
- } catch (err) {
- toast.error(err.message);
+ if (!collection || !location.pathname.startsWith(collection?.url)) {
+ toast.success(t("Pinned to collection"));
}
},
});
@@ -583,14 +573,10 @@ export const pinDocumentToHome = createAction({
}
const document = stores.documents.get(activeDocumentId);
- try {
- await document?.pin();
+ await document?.pin();
- if (location.pathname !== homePath()) {
- toast.success(t("Pinned to home"));
- }
- } catch (err) {
- toast.error(err.message);
+ if (location.pathname !== homePath()) {
+ toast.success(t("Pinned to home"));
}
},
});
@@ -641,21 +627,16 @@ export const importDocument = createAction({
input.onchange = async (ev) => {
const files = getEventFiles(ev);
- try {
- const file = files[0];
- const document = await documents.import(
- file,
- activeDocumentId,
- activeCollectionId,
- {
- publish: true,
- }
- );
- history.push(document.url);
- } catch (err) {
- toast.error(err.message);
- throw err;
- }
+ const file = files[0];
+ const document = await documents.import(
+ file,
+ activeDocumentId,
+ activeCollectionId,
+ {
+ publish: true,
+ }
+ );
+ history.push(document.url);
};
input.click();
diff --git a/app/actions/index.ts b/app/actions/index.ts
index 4083bcc10..d5e2af267 100644
--- a/app/actions/index.ts
+++ b/app/actions/index.ts
@@ -74,13 +74,7 @@ export function actionToMenuItem(
icon,
visible,
dangerous: action.dangerous,
- onClick: () => {
- try {
- action.perform?.(context);
- } catch (err) {
- toast.error(err.message);
- }
- },
+ onClick: () => performAction(action, context),
selected: action.selected?.(context),
};
}
@@ -114,10 +108,18 @@ export function actionToKBar(
keywords: action.keywords ?? "",
shortcut: action.shortcut || [],
icon: resolvedIcon,
- perform: action.perform ? () => action.perform?.(context) : undefined,
+ perform: action.perform
+ ? () => performAction(action, context)
+ : undefined,
},
].concat(
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
children.map((child) => ({ ...child, parent: child.parent ?? action.id }))
);
}
+
+export async function performAction(action: Action, context: ActionContext) {
+ return action.perform?.(context).catch((err: Error) => {
+ toast.error(err.message);
+ });
+}
diff --git a/app/components/ActionButton.tsx b/app/components/ActionButton.tsx
index d2b686182..eb67d988d 100644
--- a/app/components/ActionButton.tsx
+++ b/app/components/ActionButton.tsx
@@ -1,6 +1,7 @@
/* eslint-disable react/prop-types */
import * as React from "react";
import Tooltip, { Props as TooltipProps } from "~/components/Tooltip";
+import { performAction } from "~/actions";
import { Action, ActionContext } from "~/types";
export type Props = React.HTMLAttributes & {
@@ -60,10 +61,10 @@ const ActionButton = React.forwardRef(
? (ev) => {
ev.preventDefault();
ev.stopPropagation();
- const response = action.perform?.(actionContext);
+ const response = performAction(action, actionContext);
if (response?.finally) {
setExecuting(true);
- response.finally(() => setExecuting(false));
+ void response.finally(() => setExecuting(false));
}
}
: rest.onClick
diff --git a/app/types.ts b/app/types.ts
index b9f59c6de..74b7d9514 100644
--- a/app/types.ts
+++ b/app/types.ts
@@ -107,6 +107,10 @@ export type Action = {
placeholder?: ((context: ActionContext) => string) | string;
selected?: (context: ActionContext) => boolean;
visible?: (context: ActionContext) => boolean;
+ /**
+ * Perform the action – note this should generally not be called directly, use `performAction`
+ * instead. Errors will be caught and displayed to the user as a toast message.
+ */
perform?: (context: ActionContext) => Promise | any;
children?: ((context: ActionContext) => Action[]) | Action[];
};