Stubbed out global commands helper

This commit is contained in:
Gregory Schier
2024-03-16 09:46:11 -07:00
parent 40f8a41a8d
commit 49da0e5aa8
8 changed files with 104 additions and 59 deletions

View File

@@ -1,10 +1,9 @@
import { createBrowserRouter, Navigate, Outlet, RouterProvider, useParams } from 'react-router-dom';
import { createBrowserRouter, Navigate, RouterProvider, useParams } from 'react-router-dom';
import { routePaths, useAppRoutes } from '../hooks/useAppRoutes';
import { DialogProvider } from './DialogContext';
import { GlobalHooks } from './GlobalHooks';
import { DefaultLayout } from './DefaultLayout';
import { RedirectToLatestWorkspace } from './RedirectToLatestWorkspace';
import RouteError from './RouteError';
import Workspace from './Workspace';
import { RedirectToLatestWorkspace } from './RedirectToLatestWorkspace';
const router = createBrowserRouter([
{
@@ -58,7 +57,7 @@ function RedirectLegacyEnvironmentURLs() {
}>();
const environmentId = rawEnvironmentId === '__default__' ? undefined : rawEnvironmentId;
let to = '/';
let to;
if (workspaceId != null && requestId != null) {
to = routes.paths.request({ workspaceId, environmentId, requestId });
} else if (workspaceId != null) {
@@ -69,12 +68,3 @@ function RedirectLegacyEnvironmentURLs() {
return <Navigate to={to} />;
}
function DefaultLayout() {
return (
<DialogProvider>
<Outlet />
<GlobalHooks />
</DialogProvider>
);
}

View File

@@ -0,0 +1,12 @@
import { Outlet } from 'react-router-dom';
import { DialogProvider } from './DialogContext';
import { GlobalHooks } from './GlobalHooks';
export function DefaultLayout() {
return (
<DialogProvider>
<Outlet />
<GlobalHooks />
</DialogProvider>
);
}

View File

@@ -3,6 +3,7 @@ import { appWindow } from '@tauri-apps/api/window';
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { cookieJarsQueryKey } from '../hooks/useCookieJars';
import { useGlobalCommands } from '../hooks/useGlobalCommands';
import { grpcConnectionsQueryKey } from '../hooks/useGrpcConnections';
import { grpcEventsQueryKey } from '../hooks/useGrpcEvents';
import { grpcRequestsQueryKey } from '../hooks/useGrpcRequests';
@@ -32,8 +33,8 @@ export function GlobalHooks() {
useRecentRequests();
useSyncAppearance();
useSyncWindowTitle();
useGlobalCommands();
const queryClient = useQueryClient();
const { wasUpdatedExternally } = useRequestUpdateKey(null);

View File

@@ -24,7 +24,7 @@ export function RedirectToLatestWorkspace() {
navigate(routes.paths.workspace({ workspaceId, environmentId }));
}
})();
}, [navigate, routes.paths, workspaces, workspaces.length]);
}, [navigate, recentWorkspaces, routes.paths, workspaces, workspaces.length]);
return <></>;
}

View File

@@ -3,7 +3,7 @@ import classNames from 'classnames';
import { memo, useMemo } from 'react';
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
import { useAppRoutes } from '../hooks/useAppRoutes';
import { useCreateWorkspace } from '../hooks/useCreateWorkspace';
import { useCommand } from '../hooks/useCommands';
import { useDeleteWorkspace } from '../hooks/useDeleteWorkspace';
import { usePrompt } from '../hooks/usePrompt';
import { getRecentEnvironments } from '../hooks/useRecentEnvironments';
@@ -30,7 +30,7 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({
const activeWorkspaceId = activeWorkspace?.id ?? null;
const updateWorkspace = useUpdateWorkspace(activeWorkspaceId);
const deleteWorkspace = useDeleteWorkspace(activeWorkspace);
const createWorkspace = useCreateWorkspace({ navigateAfter: true });
const createWorkspace = useCommand('workspace.create');
const dialog = useDialog();
const prompt = usePrompt();
const routes = useAppRoutes();

View File

@@ -0,0 +1,41 @@
import type { UseMutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { useEffect } from 'react';
import { createGlobalState } from 'react-use';
import type { TrackAction, TrackResource } from '../lib/analytics';
import type { Workspace } from '../lib/models';
interface CommandInstance<T, V> extends UseMutationOptions<V, unknown, T> {
track?: [TrackResource, TrackAction];
name: string;
}
export type Commands = {
'workspace.create': CommandInstance<Partial<Pick<Workspace, 'name'>>, Workspace>;
};
const useCommandState = createGlobalState<Commands>();
export function useRegisterCommand<K extends keyof Commands>(action: K, command: Commands[K]) {
const [, setState] = useCommandState();
useEffect(() => {
setState((commands) => {
return { ...commands, [action]: command };
});
// Remove action when it goes out of scope
return () => {
setState((commands) => {
return { ...commands, [action]: undefined };
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [action]);
}
export function useCommand<K extends keyof Commands>(action: K) {
const [commands] = useCommandState();
const cmd = commands[action];
return useMutation({ ...cmd });
}

View File

@@ -1,14 +1,18 @@
import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import { trackEvent } from '../lib/analytics';
import type { Workspace } from '../lib/models';
import { useAppRoutes } from './useAppRoutes';
import { useRegisterCommand } from './useCommands';
import { usePrompt } from './usePrompt';
export function useCreateWorkspace({ navigateAfter }: { navigateAfter: boolean }) {
const routes = useAppRoutes();
export function useGlobalCommands() {
const prompt = usePrompt();
return useMutation<Workspace, unknown, Partial<Pick<Workspace, 'name'>>>({
const routes = useAppRoutes();
useRegisterCommand('workspace.create', {
name: 'New Workspace',
track: ['workspace', 'create'],
onSuccess: async (workspace) => {
routes.navigate('workspace', { workspaceId: workspace.id });
},
mutationFn: async ({ name: patchName }) => {
const name =
patchName ??
@@ -23,11 +27,5 @@ export function useCreateWorkspace({ navigateAfter }: { navigateAfter: boolean }
}));
return invoke('cmd_create_workspace', { name });
},
onSettled: () => trackEvent('workspace', 'create'),
onSuccess: async (workspace) => {
if (navigateAfter) {
routes.navigate('workspace', { workspaceId: workspace.id });
}
},
});
}

View File

@@ -1,35 +1,38 @@
import { invoke } from '@tauri-apps/api';
export function trackEvent(
resource:
| 'app'
| 'cookie_jar'
| 'dialog'
| 'environment'
| 'folder'
| 'grpc_connection'
| 'grpc_event'
| 'grpc_request'
| 'http_request'
| 'http_response'
| 'key_value'
| 'setting'
| 'sidebar'
| 'workspace',
action:
| 'cancel'
| 'commit'
| 'create'
| 'delete'
| 'delete_many'
| 'duplicate'
| 'hide'
| 'launch'
| 'send'
| 'show'
| 'toggle'
| 'update',
export type TrackResource =
| 'app'
| 'cookie_jar'
| 'dialog'
| 'environment'
| 'folder'
| 'grpc_connection'
| 'grpc_event'
| 'grpc_request'
| 'http_request'
| 'http_response'
| 'key_value'
| 'setting'
| 'sidebar'
| 'workspace';
export type TrackAction =
| 'cancel'
| 'commit'
| 'create'
| 'delete'
| 'delete_many'
| 'duplicate'
| 'hide'
| 'launch'
| 'send'
| 'show'
| 'toggle'
| 'update';
export function trackEvent(
resource: TrackResource,
action: TrackAction,
attributes: Record<string, string | number> = {},
) {
invoke('cmd_track_event', {