diff --git a/plugins/action-copy-curl/src/index.ts b/plugins/action-copy-curl/src/index.ts index af6eeb9a..ff6f5ffe 100644 --- a/plugins/action-copy-curl/src/index.ts +++ b/plugins/action-copy-curl/src/index.ts @@ -22,6 +22,45 @@ export const plugin: PluginDefinition = { }, }, ], + websocketRequestActions: [ + { + label: 'Test WebSocket Action', + icon: 'bug', + async onSelect(ctx, args) { + await ctx.toast.show({ + message: `WebSocket action called for: ${args.websocketRequest.name}`, + icon: 'bug', + color: 'info', + }); + }, + }, + ], + workspaceActions: [ + { + label: 'Test Workspace Action', + icon: 'bug', + async onSelect(ctx, args) { + await ctx.toast.show({ + message: `Workspace action called for: ${args.workspace.name}`, + icon: 'bug', + color: 'info', + }); + }, + }, + ], + folderActions: [ + { + label: 'Test Folder Action', + icon: 'bug', + async onSelect(ctx, args) { + await ctx.toast.show({ + message: `Folder action called for: ${args.folder.name}`, + icon: 'bug', + color: 'info', + }); + }, + }, + ], }; export async function convertToCurl(request: Partial) { diff --git a/src-web/components/Sidebar.tsx b/src-web/components/Sidebar.tsx index da04a1b0..80284eba 100644 --- a/src-web/components/Sidebar.tsx +++ b/src-web/components/Sidebar.tsx @@ -37,6 +37,7 @@ import { getCreateDropdownItems } from '../hooks/useCreateDropdownItems'; import { getGrpcRequestActions } from '../hooks/useGrpcRequestActions'; import { useHotKey } from '../hooks/useHotKey'; import { getHttpRequestActions } from '../hooks/useHttpRequestActions'; +import { getWebSocketRequestActions } from '../hooks/useWebSocketRequestActions'; import { getWorkspaceActions } from '../hooks/useWorkspaceActions'; import { getFolderActions } from '../hooks/useFolderActions'; import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent'; @@ -376,6 +377,17 @@ function Sidebar({ className }: { className?: string }) { if (request != null) await a.call(request); }, })), + ...(items.length === 1 && child.model === 'websocket_request' + ? await getWebSocketRequestActions() + : [] + ).map((a) => ({ + label: a.label, + leftSlot: , + onSelect: async () => { + const request = getModel('websocket_request', child.id); + if (request != null) await a.call(request); + }, + })), ...(items.length === 1 && child.model === 'workspace' ? await getWorkspaceActions() : [] diff --git a/src-web/hooks/useWebSocketRequestActions.ts b/src-web/hooks/useWebSocketRequestActions.ts new file mode 100644 index 00000000..73badd0c --- /dev/null +++ b/src-web/hooks/useWebSocketRequestActions.ts @@ -0,0 +1,52 @@ +import { useQuery } from '@tanstack/react-query'; +import type { WebsocketRequest } from '@yaakapp-internal/models'; +import type { + CallWebSocketRequestActionRequest, + GetWebSocketRequestActionsResponse, + WebSocketRequestAction, +} from '@yaakapp-internal/plugins'; +import { useMemo } from 'react'; +import { invokeCmd } from '../lib/tauri'; +import { usePluginsKey } from './usePlugins'; + +export type CallableWebSocketRequestAction = Pick & { + call: (request: WebsocketRequest) => Promise; +}; + +export function useWebSocketRequestActions() { + const pluginsKey = usePluginsKey(); + + const actionsResult = useQuery({ + queryKey: ['websocket_request_actions', pluginsKey], + queryFn: () => getWebSocketRequestActions(), + }); + + // biome-ignore lint/correctness/useExhaustiveDependencies: none + const actions = useMemo(() => { + return actionsResult.data ?? []; + }, [JSON.stringify(actionsResult.data)]); + + return actions; +} + +export async function getWebSocketRequestActions() { + const responses = await invokeCmd( + 'cmd_websocket_request_actions', + ); + const actions = responses.flatMap((r) => + r.actions.map((a, i) => ({ + label: a.label, + icon: a.icon, + call: async (websocketRequest: WebsocketRequest) => { + const payload: CallWebSocketRequestActionRequest = { + index: i, + pluginRefId: r.pluginRefId, + args: { websocketRequest }, + }; + await invokeCmd('cmd_call_websocket_request_action', { req: payload }); + }, + })), + ); + + return actions; +}