Better mutation errors and fix workspace creation

This commit is contained in:
Gregory Schier
2025-01-15 07:40:35 -08:00
parent 0e21d901cd
commit 3614c2acd5
8 changed files with 31 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type AnalyticsAction = "cancel" | "click" | "commit" | "create" | "delete" | "delete_many" | "duplicate" | "export" | "hide" | "import" | "launch" | "launch_first" | "launch_update" | "send" | "show" | "toggle" | "update" | "upsert"; export type AnalyticsAction = "cancel" | "click" | "commit" | "create" | "delete" | "delete_many" | "duplicate" | "error" | "export" | "hide" | "import" | "launch" | "launch_first" | "launch_update" | "send" | "show" | "toggle" | "update" | "upsert";
export type AnalyticsResource = "app" | "appearance" | "button" | "checkbox" | "cookie_jar" | "dialog" | "environment" | "folder" | "grpc_connection" | "grpc_event" | "grpc_request" | "http_request" | "http_response" | "link" | "key_value" | "plugin" | "select" | "setting" | "sidebar" | "tab" | "theme" | "workspace"; export type AnalyticsResource = "app" | "appearance" | "button" | "checkbox" | "cookie_jar" | "dialog" | "environment" | "folder" | "grpc_connection" | "grpc_event" | "grpc_request" | "http_request" | "http_response" | "key_value" | "link" | "mutation" | "plugin" | "select" | "setting" | "sidebar" | "tab" | "theme" | "workspace";

View File

@@ -33,8 +33,9 @@ pub enum AnalyticsResource {
GrpcRequest, GrpcRequest,
HttpRequest, HttpRequest,
HttpResponse, HttpResponse,
Link,
KeyValue, KeyValue,
Link,
Mutation,
Plugin, Plugin,
Select, Select,
Setting, Setting,
@@ -67,6 +68,7 @@ pub enum AnalyticsAction {
Delete, Delete,
DeleteMany, DeleteMany,
Duplicate, Duplicate,
Error,
Export, Export,
Hide, Hide,
Import, Import,

View File

@@ -58,7 +58,7 @@ export type SyncHistory = { model: "sync_history", id: string, workspaceId: stri
export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, }; export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, };
export type UpdateSource = "sync" | "window" | "plugin" | "background"; export type UpdateSource = "sync" | "window" | "plugin" | "background" | "import";
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, }; export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };

View File

@@ -4,7 +4,7 @@ import { createFastMutation } from '../hooks/useFastMutation';
import { showSimpleAlert } from '../lib/alert'; import { showSimpleAlert } from '../lib/alert';
import { router } from '../lib/router'; import { router } from '../lib/router';
export const openWorkspaceFromSyncDir = createFastMutation({ export const openWorkspaceFromSyncDir = createFastMutation<void>({
mutationKey: [], mutationKey: [],
mutationFn: async () => { mutationFn: async () => {
const dir = await open({ const dir = await open({

View File

@@ -5,15 +5,16 @@ import { getRecentRequests } from '../hooks/useRecentRequests';
import { router } from '../lib/router'; import { router } from '../lib/router';
import { invokeCmd } from '../lib/tauri'; import { invokeCmd } from '../lib/tauri';
export const switchWorkspace = createFastMutation({ export const switchWorkspace = createFastMutation<
mutationKey: ['open_workspace'], void,
mutationFn: async ({ unknown,
workspaceId, {
inNewWindow,
}: {
workspaceId: string; workspaceId: string;
inNewWindow: boolean; inNewWindow: boolean;
}) => { }
>({
mutationKey: ['open_workspace'],
mutationFn: async ({ workspaceId, inNewWindow }) => {
const environmentId = (await getRecentEnvironments(workspaceId))[0] ?? undefined; const environmentId = (await getRecentEnvironments(workspaceId))[0] ?? undefined;
const requestId = (await getRecentRequests(workspaceId))[0] ?? undefined; const requestId = (await getRecentRequests(workspaceId))[0] ?? undefined;
const cookieJarId = (await getRecentCookieJars(workspaceId))[0] ?? undefined; const cookieJarId = (await getRecentCookieJars(workspaceId))[0] ?? undefined;

View File

@@ -24,7 +24,6 @@ export function CreateWorkspaceDialog({ hide }: Props) {
className="pb-3 max-h-[50vh]" className="pb-3 max-h-[50vh]"
onSubmit={async (e) => { onSubmit={async (e) => {
e.preventDefault(); e.preventDefault();
if (!settingSyncDir) return;
const workspace = await upsertWorkspace.mutateAsync({ name }); const workspace = await upsertWorkspace.mutateAsync({ name });
if (workspace == null) return; if (workspace == null) return;

View File

@@ -16,7 +16,7 @@ export const Toasts = () => {
const toasts = useAtomValue(toastsAtom); const toasts = useAtomValue(toastsAtom);
return ( return (
<Portal name="toasts"> <Portal name="toasts">
<div className="absolute right-0 bottom-0 z-20"> <div className="absolute right-0 bottom-0 z-50">
<AnimatePresence> <AnimatePresence>
{toasts.map(({ message, ...props }: ToastInstance) => ( {toasts.map(({ message, ...props }: ToastInstance) => (
<Toast <Toast

View File

@@ -1,5 +1,7 @@
import type { MutationKey } from '@tanstack/react-query'; import type { MutationKey } from '@tanstack/react-query';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { showToast } from '../lib/toast';
import { trackEvent } from '../lib/analytics';
interface MutationOptions<TData, TError, TVariables> { interface MutationOptions<TData, TError, TVariables> {
mutationKey: MutationKey; mutationKey: MutationKey;
@@ -7,6 +9,7 @@ interface MutationOptions<TData, TError, TVariables> {
onSettled?: () => void; onSettled?: () => void;
onError?: (err: TError) => void; onError?: (err: TError) => void;
onSuccess?: (data: TData) => void; onSuccess?: (data: TData) => void;
disableToastError?: boolean;
} }
type CallbackMutationOptions<TData, TError, TVariables> = Omit< type CallbackMutationOptions<TData, TError, TVariables> = Omit<
@@ -21,7 +24,7 @@ export function createFastMutation<TData = unknown, TError = unknown, TVariables
variables: TVariables, variables: TVariables,
args?: CallbackMutationOptions<TData, TError, TVariables>, args?: CallbackMutationOptions<TData, TError, TVariables>,
) => { ) => {
const { mutationKey, mutationFn, onSuccess, onError, onSettled } = { const { mutationKey, mutationFn, onSuccess, onError, onSettled, disableToastError } = {
...defaultArgs, ...defaultArgs,
...args, ...args,
}; };
@@ -30,8 +33,18 @@ export function createFastMutation<TData = unknown, TError = unknown, TVariables
onSuccess?.(data); onSuccess?.(data);
return data; return data;
} catch (err: unknown) { } catch (err: unknown) {
const stringKey = mutationKey.join('.');
const e = err as TError; const e = err as TError;
console.log('Fast mutation error', mutationKey, e); console.log('mutation error', stringKey, e);
trackEvent('mutation', 'error', { key: stringKey });
if (!disableToastError) {
showToast({
id: stringKey,
message: `${err}`,
color: 'danger',
timeout: 5000,
});
}
onError?.(e); onError?.(e);
} finally { } finally {
onSettled?.(); onSettled?.();