@motiadev/workbench 0.5.11-beta.120-742949 → 0.5.11-beta.120-433270

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/App.js CHANGED
@@ -1,9 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { CollapsiblePanel, CollapsiblePanelGroup, TabsContent, TabsList, TabsTrigger } from '@motiadev/ui';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CollapsiblePanel, CollapsiblePanelGroup, Panel, TabsContent, TabsList, TabsTrigger } from '@motiadev/ui';
3
3
  import { ReactFlowProvider } from '@xyflow/react';
4
4
  import { analytics } from '@/lib/analytics';
5
5
  import { File, GanttChart, Link2, LogsIcon } from 'lucide-react';
6
- import { useCallback, useMemo } from 'react';
6
+ import { useCallback, useEffect, useMemo, useState } from 'react';
7
7
  import { EndpointsPage } from './components/endpoints/endpoints-page';
8
8
  import { FlowPage } from './components/flow/flow-page';
9
9
  import { FlowTabMenuItem } from './components/flow/flow-tab-menu-item';
@@ -22,6 +22,7 @@ export const App = () => {
22
22
  const tab = useTabsStore((state) => state.tab);
23
23
  const setTopTab = useTabsStore((state) => state.setTopTab);
24
24
  const setBottomTab = useTabsStore((state) => state.setBottomTab);
25
+ const [viewMode, setViewMode] = useState('system');
25
26
  const tabChangeCallbacks = useMemo(() => ({
26
27
  [TabLocation.TOP]: setTopTab,
27
28
  [TabLocation.BOTTOM]: setBottomTab,
@@ -30,5 +31,26 @@ export const App = () => {
30
31
  analytics.track(`${location} tab changed`, { [`new.${location}`]: newTab, tab });
31
32
  tabChangeCallbacks[location](newTab);
32
33
  }, [tabChangeCallbacks, tab]);
34
+ useEffect(() => {
35
+ const url = new URL(window.location.href);
36
+ const viewMode = url.searchParams.get('view-mode');
37
+ if (viewMode) {
38
+ setViewMode(viewMode);
39
+ }
40
+ }, [setViewMode]);
41
+ if (viewMode === 'project') {
42
+ return (_jsxs("div", { className: "grid grid-rows-[auto_1fr] grid-cols-[1fr_auto] bg-background text-foreground h-screen ", children: [_jsx("main", { className: "m-2 overflow-hidden", role: "main", children: _jsx(Panel, { tabs: [
43
+ {
44
+ label: 'Flow',
45
+ labelComponent: _jsx(FlowTabMenuItem, {}),
46
+ content: (_jsx(ReactFlowProvider, { children: _jsx("div", { className: "h-[calc(100vh-100px)] w-full", children: _jsx(FlowPage, {}) }) })),
47
+ },
48
+ {
49
+ label: 'Endpoint',
50
+ labelComponent: (_jsxs(_Fragment, { children: [_jsx(Link2, {}), "Endpoint"] })),
51
+ content: _jsx(EndpointsPage, {}),
52
+ },
53
+ ] }) }), _jsx("div", { id: APP_SIDEBAR_CONTAINER_ID })] }));
54
+ }
33
55
  return (_jsxs("div", { className: "grid grid-rows-[auto_1fr] grid-cols-[1fr_auto] bg-background text-foreground h-screen", children: [_jsx("div", { className: "col-span-2", children: _jsx(Header, {}) }), _jsx("main", { className: "m-2 overflow-hidden", role: "main", children: _jsxs(CollapsiblePanelGroup, { autoSaveId: "app-panel", direction: "vertical", className: "gap-1 h-full", "aria-label": "Workbench panels", children: [_jsxs(CollapsiblePanel, { id: "top-panel", variant: 'tabs', defaultTab: tab.top, onTabChange: onTabChange(TabLocation.TOP), header: _jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "flow", "data-testid": "flows-link", children: _jsx(FlowTabMenuItem, {}) }), _jsxs(TabsTrigger, { value: "endpoint", "data-testid": "endpoints-link", className: "cursor-pointer", children: [_jsx(Link2, {}), "Endpoint"] })] }), children: [_jsx(TabsContent, { value: "flow", className: "h-full", asChild: true, children: _jsx(ReactFlowProvider, { children: _jsx(FlowPage, {}) }) }), _jsx(TabsContent, { value: "endpoint", asChild: true, children: _jsx(EndpointsPage, {}) })] }), _jsxs(CollapsiblePanel, { id: "bottom-panel", variant: 'tabs', defaultTab: tab.bottom, onTabChange: onTabChange(TabLocation.BOTTOM), header: _jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "tracing", "data-testid": "traces-link", className: "cursor-pointer", children: [_jsx(GanttChart, {}), " Tracing"] }), _jsxs(TabsTrigger, { value: "logs", "data-testid": "logs-link", className: "cursor-pointer", children: [_jsx(LogsIcon, {}), "Logs"] }), _jsxs(TabsTrigger, { value: "states", "data-testid": "states-link", className: "cursor-pointer", children: [_jsx(File, {}), "States"] })] }), children: [_jsx(TabsContent, { value: "tracing", className: "max-h-fit", asChild: true, children: _jsx(TracesPage, {}) }), _jsx(TabsContent, { value: "logs", asChild: true, children: _jsx(LogsPage, {}) }), _jsx(TabsContent, { value: "states", asChild: true, children: _jsx(StatesPage, {}) })] })] }) }), _jsx("div", { id: APP_SIDEBAR_CONTAINER_ID })] }));
34
56
  };
@@ -6,6 +6,7 @@ type Props = {
6
6
  endpoint: ApiEndpoint;
7
7
  onChange?: (body: string) => void;
8
8
  onValidate?: (isValid: boolean) => void;
9
+ panelName: string;
9
10
  };
10
11
  export declare const EndpointBodyPanel: FC<Props>;
11
12
  export {};
@@ -6,7 +6,7 @@ import ReactJson from 'react18-json-view';
6
6
  import 'react18-json-view/src/dark.css';
7
7
  import 'react18-json-view/src/style.css';
8
8
  import { convertJsonSchemaToJson } from './hooks/utils';
9
- export const EndpointBodyPanel = ({ endpoint, onChange, onValidate }) => {
9
+ export const EndpointBodyPanel = ({ endpoint, onChange, onValidate, panelName }) => {
10
10
  const shouldHaveBody = ['post', 'put', 'patch'].includes(endpoint.method.toLowerCase());
11
11
  const { body, setBody } = useJsonSchemaToJson(endpoint.bodySchema);
12
12
  const handleBodyChange = (body) => {
@@ -16,5 +16,5 @@ export const EndpointBodyPanel = ({ endpoint, onChange, onValidate }) => {
16
16
  if (!shouldHaveBody) {
17
17
  return null;
18
18
  }
19
- return (_jsx(Panel, { title: "Body", size: "sm", contentClassName: "p-0", "data-testid": "endpoint-body-panel", children: onChange ? (_jsx(JsonEditor, { value: body, schema: endpoint.bodySchema, onChange: handleBodyChange, onValidate: onValidate })) : (_jsx(ReactJson, { src: convertJsonSchemaToJson(endpoint.bodySchema), theme: "default", enableClipboard: false, style: { backgroundColor: 'transparent' } })) }));
19
+ return (_jsx(Panel, { title: "Body", size: "sm", contentClassName: "p-0", "data-testid": `endpoint-body-panel__${panelName}`, children: onChange ? (_jsx(JsonEditor, { value: body, schema: endpoint.bodySchema, onChange: handleBodyChange, onValidate: onValidate })) : (_jsx(ReactJson, { src: convertJsonSchemaToJson(endpoint.bodySchema), theme: "default", enableClipboard: false, style: { backgroundColor: 'transparent' } })) }));
20
20
  };
@@ -53,5 +53,5 @@ export const EndpointCall = ({ endpoint }) => {
53
53
  setExecutionTime(executionTime);
54
54
  setIsRequestLoading(false);
55
55
  };
56
- return (_jsxs("div", { className: "space-y-3", children: [_jsx(EndpointPathParamsPanel, { endpoint: endpoint, onChange: setPathParamsValues }), _jsx(EndpointQueryParamsPanel, { endpoint: endpoint, onChange: setQueryParamsValues }), _jsx(EndpointBodyPanel, { endpoint: endpoint, onChange: setBody, onValidate: setIsBodyValid }), _jsxs(Button, { className: "w-fit", onClick: handleRequest, variant: "accent", "data-testid": "endpoint-play-button", disabled: isRequestLoading || !isPlayEnabled, children: [isRequestLoading ? _jsx(Loader2, { className: "animate-spin" }) : _jsx(Play, {}), " Play"] }), _jsx(EndpointResponse, { responseCode: responseCode, responseBody: responseBody, executionTime: executionTime })] }));
56
+ return (_jsxs("div", { className: "space-y-3", children: [_jsx(EndpointPathParamsPanel, { endpoint: endpoint, onChange: setPathParamsValues }), _jsx(EndpointQueryParamsPanel, { endpoint: endpoint, onChange: setQueryParamsValues }), _jsx(EndpointBodyPanel, { endpoint: endpoint, onChange: setBody, onValidate: setIsBodyValid, panelName: "call" }), _jsxs(Button, { className: "w-fit", onClick: handleRequest, variant: "accent", "data-testid": "endpoint-play-button", disabled: isRequestLoading || !isPlayEnabled, children: [isRequestLoading ? _jsx(Loader2, { className: "animate-spin" }) : _jsx(Play, {}), " Play"] }), _jsx(EndpointResponse, { responseCode: responseCode, responseBody: responseBody, executionTime: executionTime })] }));
57
57
  };
@@ -4,7 +4,7 @@ import { EndpointPathParamsPanel } from './endpoint-path-params-panel';
4
4
  import { EndpointQueryParamsPanel } from './endpoint-query-params-panel';
5
5
  import { EndpointBodyPanel } from './endpoint-body-panel';
6
6
  export const EndpointDescription = ({ endpoint }) => {
7
- return (_jsxs("div", { className: "space-y-3", children: [_jsx(EndpointPathParamsPanel, { endpoint: endpoint }), _jsx(EndpointQueryParamsPanel, { endpoint: endpoint }), _jsx(EndpointBodyPanel, { endpoint: endpoint }), _jsx(EndpointResponseSchema, { items: Object.entries(endpoint?.responseSchema ?? {}).map(([status, schema]) => ({
7
+ return (_jsxs("div", { className: "space-y-3", children: [_jsx(EndpointPathParamsPanel, { endpoint: endpoint }), _jsx(EndpointQueryParamsPanel, { endpoint: endpoint }), _jsx(EndpointBodyPanel, { endpoint: endpoint, panelName: "details" }), _jsx(EndpointResponseSchema, { items: Object.entries(endpoint?.responseSchema ?? {}).map(([status, schema]) => ({
8
8
  responseCode: status,
9
9
  bodySchema: schema,
10
10
  })) })] }));
@@ -2,11 +2,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Moon, Sun } from 'lucide-react';
3
3
  import { useThemeStore } from '@/stores/use-theme-store';
4
4
  import { cn } from '@/lib/utils';
5
+ import { useEffect } from 'react';
5
6
  export const ThemeToggle = () => {
6
7
  const theme = useThemeStore((state) => state.theme);
7
8
  const setTheme = useThemeStore((state) => state.setTheme);
8
9
  const toggleTheme = () => {
9
10
  setTheme(theme === 'light' ? 'dark' : 'light');
10
11
  };
12
+ useEffect(() => {
13
+ const url = new URL(window.location.href);
14
+ const colorScheme = url.searchParams.get('color-scheme');
15
+ if (colorScheme) {
16
+ setTheme(colorScheme);
17
+ }
18
+ }, [setTheme]);
11
19
  return (_jsxs("button", { onClick: toggleTheme, className: "relative flex items-center cursor-pointer w-16 h-8 border bg-muted-foreground/10 rounded-full p-1 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", "aria-label": `Switch to ${theme === 'light' ? 'dark' : 'light'} theme`, children: [_jsx("div", { className: cn('absolute w-6 h-6 bg-background border border-border rounded-full shadow-sm transition-transform duration-200 ease-in-out', theme === 'dark' ? 'translate-x-8' : 'translate-x-0') }), _jsx("div", { className: "flex items-center justify-center w-6 h-6 z-10", children: _jsx(Sun, { className: cn('h-3.5 w-3.5 transition-colors duration-200', theme === 'light' ? 'text-foreground' : 'text-muted-foreground') }) }), _jsx("div", { className: "flex items-center justify-center w-6 h-6 z-10 ml-2", children: _jsx(Moon, { className: cn('h-3.5 w-3.5 transition-colors duration-200', theme === 'dark' ? 'text-foreground' : 'text-muted-foreground') }) })] }));
12
20
  };
@@ -4,15 +4,17 @@ type UseFlowStore = {
4
4
  flows: string[];
5
5
  setFlows: (flows: string[]) => void;
6
6
  };
7
- export declare const useFlowStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseFlowStore>, "persist"> & {
7
+ export declare const useFlowStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseFlowStore>, "setState" | "persist"> & {
8
+ setState(partial: UseFlowStore | Partial<UseFlowStore> | ((state: UseFlowStore) => UseFlowStore | Partial<UseFlowStore>), replace?: false | undefined): unknown;
9
+ setState(state: UseFlowStore | ((state: UseFlowStore) => UseFlowStore), replace: true): unknown;
8
10
  persist: {
9
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore>>) => void;
11
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore, unknown>>) => void;
10
12
  clearStorage: () => void;
11
13
  rehydrate: () => Promise<void> | void;
12
14
  hasHydrated: () => boolean;
13
15
  onHydrate: (fn: (state: UseFlowStore) => void) => () => void;
14
16
  onFinishHydration: (fn: (state: UseFlowStore) => void) => () => void;
15
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore>>;
17
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseFlowStore, UseFlowStore, unknown>>;
16
18
  };
17
19
  }>;
18
20
  export {};
@@ -10,15 +10,17 @@ type UseGlobalStore = {
10
10
  selectedLogId?: string;
11
11
  selectLogId: (logId?: string) => void;
12
12
  };
13
- export declare const useGlobalStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseGlobalStore>, "persist"> & {
13
+ export declare const useGlobalStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UseGlobalStore>, "setState" | "persist"> & {
14
+ setState(partial: UseGlobalStore | Partial<UseGlobalStore> | ((state: UseGlobalStore) => UseGlobalStore | Partial<UseGlobalStore>), replace?: false | undefined): unknown;
15
+ setState(state: UseGlobalStore | ((state: UseGlobalStore) => UseGlobalStore), replace: true): unknown;
14
16
  persist: {
15
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore>>) => void;
17
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore, unknown>>) => void;
16
18
  clearStorage: () => void;
17
19
  rehydrate: () => Promise<void> | void;
18
20
  hasHydrated: () => boolean;
19
21
  onHydrate: (fn: (state: UseGlobalStore) => void) => () => void;
20
22
  onFinishHydration: (fn: (state: UseGlobalStore) => void) => () => void;
21
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore>>;
23
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<UseGlobalStore, UseGlobalStore, unknown>>;
22
24
  };
23
25
  }>;
24
26
  export {};
@@ -3,15 +3,17 @@ interface TabsState {
3
3
  setTopTab: (tab: string) => void;
4
4
  setBottomTab: (tab: string) => void;
5
5
  }
6
- export declare const useTabsStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<TabsState>, "persist"> & {
6
+ export declare const useTabsStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<TabsState>, "setState" | "persist"> & {
7
+ setState(partial: TabsState | Partial<TabsState> | ((state: TabsState) => TabsState | Partial<TabsState>), replace?: false | undefined): unknown;
8
+ setState(state: TabsState | ((state: TabsState) => TabsState), replace: true): unknown;
7
9
  persist: {
8
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<TabsState, TabsState>>) => void;
10
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<TabsState, TabsState, unknown>>) => void;
9
11
  clearStorage: () => void;
10
12
  rehydrate: () => Promise<void> | void;
11
13
  hasHydrated: () => boolean;
12
14
  onHydrate: (fn: (state: TabsState) => void) => () => void;
13
15
  onFinishHydration: (fn: (state: TabsState) => void) => () => void;
14
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<TabsState, TabsState>>;
16
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<TabsState, TabsState, unknown>>;
15
17
  };
16
18
  }>;
17
19
  export {};
@@ -1,17 +1,18 @@
1
- type Theme = 'dark' | 'light' | 'system';
1
+ export type Theme = 'dark' | 'light' | 'system';
2
2
  export type ThemeState = {
3
3
  theme: Theme;
4
4
  setTheme: (theme: Theme) => void;
5
5
  };
6
- export declare const useThemeStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<ThemeState>, "persist"> & {
6
+ export declare const useThemeStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<ThemeState>, "setState" | "persist"> & {
7
+ setState(partial: ThemeState | Partial<ThemeState> | ((state: ThemeState) => ThemeState | Partial<ThemeState>), replace?: false | undefined): unknown;
8
+ setState(state: ThemeState | ((state: ThemeState) => ThemeState), replace: true): unknown;
7
9
  persist: {
8
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown>>) => void;
10
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown, unknown>>) => void;
9
11
  clearStorage: () => void;
10
12
  rehydrate: () => Promise<void> | void;
11
13
  hasHydrated: () => boolean;
12
14
  onHydrate: (fn: (state: ThemeState) => void) => () => void;
13
15
  onFinishHydration: (fn: (state: ThemeState) => void) => () => void;
14
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown>>;
16
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown, unknown>>;
15
17
  };
16
18
  }>;
17
- export {};