@motiadev/workbench 0.3.1-beta.87 → 0.3.1-beta.88-041205
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/index.d.ts +3 -4
- package/dist/index.html +3 -2
- package/dist/index.js +2 -3
- package/dist/public/icon.png +0 -0
- package/dist/public/motia-dark.png +0 -0
- package/dist/public/motia-light.png +0 -0
- package/dist/src/App.d.ts +2 -0
- package/dist/src/App.js +19 -0
- package/dist/src/components/endpoints/endpoint-badge.d.ts +1 -1
- package/dist/src/components/endpoints/endpoint-badge.js +8 -8
- package/dist/src/components/endpoints/endpoint-call.d.ts +3 -3
- package/dist/src/components/endpoints/endpoint-call.js +28 -23
- package/dist/src/components/endpoints/endpoint-response-schema.d.ts +10 -0
- package/dist/src/components/endpoints/endpoint-response-schema.js +17 -0
- package/dist/src/components/endpoints/endpoint-response.d.ts +8 -0
- package/dist/src/components/endpoints/endpoint-response.js +39 -0
- package/dist/src/components/endpoints/endpoints-page.js +14 -0
- package/dist/src/components/endpoints/hooks/use-get-endpoints.d.ts +1 -15
- package/dist/src/components/endpoints/json-editor.d.ts +9 -0
- package/dist/src/components/endpoints/json-editor.js +31 -0
- package/dist/src/components/flow/flow-page.d.ts +1 -0
- package/dist/src/components/flow/flow-page.js +20 -0
- package/dist/src/components/flow/flow-tab-menu-item.d.ts +1 -0
- package/dist/src/components/flow/flow-tab-menu-item.js +15 -0
- package/dist/src/{views → components}/flow/flow-view.d.ts +1 -2
- package/dist/src/components/flow/flow-view.js +21 -0
- package/dist/src/components/flow/hooks/use-get-flow-state.d.ts +10 -0
- package/dist/src/{views → components}/flow/hooks/use-get-flow-state.js +17 -10
- package/dist/src/{views → components}/flow/hooks/use-organize-nodes.d.ts +1 -1
- package/dist/src/{views → components}/flow/hooks/use-save-workflow-config.d.ts +1 -1
- package/dist/src/components/flow/nodes/api-flow-node.d.ts +2 -0
- package/dist/src/{views → components}/flow/nodes/api-flow-node.js +1 -1
- package/dist/src/components/flow/nodes/cron-flow-node.d.ts +2 -0
- package/dist/src/components/flow/nodes/cron-flow-node.js +5 -0
- package/dist/src/{views → components}/flow/nodes/event-flow-node.d.ts +1 -1
- package/dist/src/components/flow/nodes/event-flow-node.js +5 -0
- package/dist/src/components/flow/nodes/noop-flow-node.d.ts +2 -0
- package/dist/src/{views → components}/flow/nodes/noop-flow-node.js +1 -1
- package/dist/src/components/header/header.js +3 -11
- package/dist/src/components/logs/log-detail.d.ts +3 -1
- package/dist/src/components/logs/log-detail.js +33 -11
- package/dist/src/components/logs/log-level-badge.js +6 -6
- package/dist/src/components/logs/log-level-dot.js +7 -7
- package/dist/src/components/logs/logs-page.js +26 -0
- package/dist/src/components/observability/events/code/function-call.js +1 -1
- package/dist/src/components/observability/events/trace-event.d.ts +1 -1
- package/dist/src/components/observability/events/trace-log-event.d.ts +1 -1
- package/dist/src/components/observability/events/trace-log-event.js +2 -2
- package/dist/src/components/observability/hooks/use-get-endtime.d.ts +1 -1
- package/dist/src/components/observability/trace-item/trace-item-detail.d.ts +1 -0
- package/dist/src/components/observability/trace-item/trace-item-detail.js +5 -4
- package/dist/src/components/observability/trace-item/trace-item.d.ts +1 -0
- package/dist/src/components/observability/trace-item/trace-item.js +11 -17
- package/dist/src/components/observability/trace-status.d.ts +6 -10
- package/dist/src/components/observability/trace-status.js +7 -32
- package/dist/src/components/observability/trace-timeline.js +16 -4
- package/dist/src/components/observability/traces-groups.d.ts +2 -2
- package/dist/src/components/observability/traces-groups.js +4 -4
- package/dist/src/components/observability/traces-page.js +12 -0
- package/dist/src/components/sidebar/sidebar.d.ts +8 -0
- package/dist/src/components/sidebar/sidebar.js +39 -0
- package/dist/src/components/states/hooks/states-hooks.d.ts +7 -3
- package/dist/src/components/states/hooks/states-hooks.js +5 -33
- package/dist/src/components/states/state-detail.d.ts +2 -1
- package/dist/src/components/states/state-detail.js +15 -9
- package/dist/src/components/states/state-value.js +7 -7
- package/dist/src/components/states/states-page.js +18 -0
- package/dist/src/components/ui/badge.d.ts +1 -1
- package/dist/src/components/ui/table.js +1 -1
- package/dist/src/components/ui/theme-toggle.js +4 -3
- package/dist/src/hooks/use-fetch-flows.d.ts +1 -5
- package/dist/src/hooks/use-fetch-flows.js +18 -13
- package/dist/src/hooks/use-log-listener.js +2 -2
- package/dist/src/hooks/use-update-handle-positions.d.ts +10 -0
- package/dist/src/hooks/use-update-handle-positions.js +35 -0
- package/dist/src/index.css +36 -176
- package/dist/src/lib/utils.d.ts +1 -0
- package/dist/src/lib/utils.js +4 -0
- package/dist/src/main.d.ts +1 -0
- package/dist/src/main.js +4 -11
- package/dist/src/publicComponents/api-node.js +2 -4
- package/dist/src/publicComponents/{base-handle.d.ts → base-node/base-handle.d.ts} +1 -0
- package/dist/src/publicComponents/base-node/base-handle.js +8 -0
- package/dist/src/publicComponents/base-node/base-node.d.ts +21 -0
- package/dist/src/publicComponents/base-node/base-node.js +13 -0
- package/dist/src/publicComponents/{emits.d.ts → base-node/emits.d.ts} +1 -1
- package/dist/src/publicComponents/base-node/emits.js +5 -0
- package/dist/src/{views/flow/nodes → publicComponents/base-node}/language-indicator.d.ts +1 -1
- package/dist/src/{views/flow/nodes → publicComponents/base-node}/language-indicator.js +8 -7
- package/dist/src/publicComponents/base-node/node-header.d.ts +12 -0
- package/dist/src/publicComponents/base-node/node-header.js +30 -0
- package/dist/src/publicComponents/base-node/node-sidebar.d.ts +18 -0
- package/dist/src/publicComponents/base-node/node-sidebar.js +20 -0
- package/dist/src/publicComponents/base-node/subscribe.js +4 -0
- package/dist/src/publicComponents/cron-node.d.ts +2 -1
- package/dist/src/publicComponents/cron-node.js +3 -4
- package/dist/src/publicComponents/event-node.d.ts +1 -5
- package/dist/src/publicComponents/event-node.js +4 -6
- package/dist/src/publicComponents/node-details.js +21 -12
- package/dist/src/publicComponents/node-props.d.ts +13 -6
- package/dist/src/publicComponents/noop-node.d.ts +3 -7
- package/dist/src/publicComponents/noop-node.js +3 -3
- package/dist/src/stores/use-flow-store.d.ts +18 -0
- package/dist/src/stores/use-flow-store.js +15 -0
- package/dist/src/stores/use-global-store.d.ts +24 -0
- package/dist/src/stores/use-global-store.js +20 -0
- package/dist/src/stores/{use-logs.d.ts → use-logs-store.d.ts} +1 -3
- package/dist/src/stores/use-logs-store.js +10 -0
- package/dist/src/stores/use-tabs-store.d.ts +17 -0
- package/dist/src/stores/use-tabs-store.js +13 -0
- package/dist/src/stores/use-theme-store.d.ts +17 -0
- package/dist/src/stores/use-theme-store.js +26 -0
- package/dist/src/types/endpoint.d.ts +14 -0
- package/dist/src/{views/flow/nodes/nodes.types.d.ts → types/flow.d.ts} +45 -0
- package/dist/src/types/flow.js +1 -0
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/package.json +13 -12
- package/dist/public/.empty +0 -0
- package/dist/src/components/app-sidebar.d.ts +0 -1
- package/dist/src/components/app-sidebar.js +0 -12
- package/dist/src/components/endpoints/endpoints.d.ts +0 -1
- package/dist/src/components/endpoints/endpoints.js +0 -34
- package/dist/src/components/endpoints/selected-endpoint.d.ts +0 -7
- package/dist/src/components/endpoints/selected-endpoint.js +0 -7
- package/dist/src/components/logs/log-console.d.ts +0 -1
- package/dist/src/components/logs/log-console.js +0 -69
- package/dist/src/components/logs/log-field.d.ts +0 -7
- package/dist/src/components/logs/log-field.js +0 -20
- package/dist/src/components/logs/logs.d.ts +0 -1
- package/dist/src/components/logs/logs.js +0 -18
- package/dist/src/components/observability/observability-stats.d.ts +0 -5
- package/dist/src/components/observability/observability-stats.js +0 -17
- package/dist/src/components/states/states.d.ts +0 -1
- package/dist/src/components/states/states.js +0 -21
- package/dist/src/components/ui/BadgeCount.d.ts +0 -7
- package/dist/src/components/ui/BadgeCount.js +0 -13
- package/dist/src/components/ui/button.d.ts +0 -11
- package/dist/src/components/ui/button.js +0 -33
- package/dist/src/components/ui/card.d.ts +0 -8
- package/dist/src/components/ui/card.js +0 -16
- package/dist/src/components/ui/collapsible.d.ts +0 -5
- package/dist/src/components/ui/collapsible.js +0 -5
- package/dist/src/components/ui/dialog.d.ts +0 -19
- package/dist/src/components/ui/dialog.js +0 -22
- package/dist/src/components/ui/dropdown-menu.d.ts +0 -25
- package/dist/src/components/ui/dropdown-menu.js +0 -50
- package/dist/src/components/ui/input.d.ts +0 -3
- package/dist/src/components/ui/input.js +0 -8
- package/dist/src/components/ui/logo-icon.d.ts +0 -5
- package/dist/src/components/ui/logo-icon.js +0 -5
- package/dist/src/components/ui/navigation-menu.d.ts +0 -13
- package/dist/src/components/ui/navigation-menu.js +0 -30
- package/dist/src/components/ui/scroll-area.d.ts +0 -5
- package/dist/src/components/ui/scroll-area.js +0 -9
- package/dist/src/components/ui/select.d.ts +0 -13
- package/dist/src/components/ui/select.js +0 -25
- package/dist/src/components/ui/separator.d.ts +0 -4
- package/dist/src/components/ui/separator.js +0 -8
- package/dist/src/components/ui/sheet.d.ts +0 -25
- package/dist/src/components/ui/sheet.js +0 -36
- package/dist/src/components/ui/sidebar.d.ts +0 -12
- package/dist/src/components/ui/sidebar.js +0 -25
- package/dist/src/components/ui/skeleton.d.ts +0 -3
- package/dist/src/components/ui/skeleton.js +0 -6
- package/dist/src/components/ui/switch.d.ts +0 -4
- package/dist/src/components/ui/switch.js +0 -7
- package/dist/src/components/ui/tabs.d.ts +0 -7
- package/dist/src/components/ui/tabs.js +0 -12
- package/dist/src/components/ui/textarea.d.ts +0 -3
- package/dist/src/components/ui/textarea.js +0 -8
- package/dist/src/components/ui/tooltip.d.ts +0 -7
- package/dist/src/components/ui/tooltip.js +0 -11
- package/dist/src/hooks/use-list-flows.d.ts +0 -9
- package/dist/src/hooks/use-list-flows.js +0 -8
- package/dist/src/hooks/use-theme.d.ts +0 -6
- package/dist/src/hooks/use-theme.js +0 -28
- package/dist/src/publicComponents/base-handle.js +0 -10
- package/dist/src/publicComponents/base-node.d.ts +0 -16
- package/dist/src/publicComponents/base-node.js +0 -25
- package/dist/src/publicComponents/colorMap.d.ts +0 -6
- package/dist/src/publicComponents/colorMap.js +0 -6
- package/dist/src/publicComponents/components/header-bar.d.ts +0 -11
- package/dist/src/publicComponents/components/header-bar.js +0 -15
- package/dist/src/publicComponents/emits.js +0 -6
- package/dist/src/publicComponents/subscribe.js +0 -5
- package/dist/src/route-wrapper.d.ts +0 -2
- package/dist/src/route-wrapper.js +0 -5
- package/dist/src/routes/endpoints-page.js +0 -5
- package/dist/src/routes/flow.d.ts +0 -1
- package/dist/src/routes/flow.js +0 -11
- package/dist/src/routes/index.d.ts +0 -1
- package/dist/src/routes/index.js +0 -5
- package/dist/src/routes/logs-page.js +0 -12
- package/dist/src/routes/states-page.js +0 -5
- package/dist/src/routes/traces-page.js +0 -14
- package/dist/src/stores/use-logs.js +0 -52
- package/dist/src/views/flow/arrow-head.d.ts +0 -8
- package/dist/src/views/flow/arrow-head.js +0 -6
- package/dist/src/views/flow/flow-view.js +0 -48
- package/dist/src/views/flow/hooks/use-get-flow-state.d.ts +0 -52
- package/dist/src/views/flow/legend.d.ts +0 -4
- package/dist/src/views/flow/legend.js +0 -51
- package/dist/src/views/flow/nodes/api-flow-node.d.ts +0 -4
- package/dist/src/views/flow/nodes/event-flow-node.js +0 -5
- package/dist/src/views/flow/nodes/noop-flow-node.d.ts +0 -4
- /package/dist/src/{routes → components/endpoints}/endpoints-page.d.ts +0 -0
- /package/dist/src/{views → components}/flow/base-edge.d.ts +0 -0
- /package/dist/src/{views → components}/flow/base-edge.js +0 -0
- /package/dist/src/{views → components}/flow/flow-loader.d.ts +0 -0
- /package/dist/src/{views → components}/flow/flow-loader.js +0 -0
- /package/dist/src/{views → components}/flow/hooks/use-organize-nodes.js +0 -0
- /package/dist/src/{views → components}/flow/hooks/use-save-workflow-config.js +0 -0
- /package/dist/src/{views → components}/flow/node-organizer.d.ts +0 -0
- /package/dist/src/{views → components}/flow/node-organizer.js +0 -0
- /package/dist/src/{routes → components/logs}/logs-page.d.ts +0 -0
- /package/dist/src/{routes → components/observability}/traces-page.d.ts +0 -0
- /package/dist/src/{routes → components/states}/states-page.d.ts +0 -0
- /package/dist/src/publicComponents/{subscribe.d.ts → base-node/subscribe.d.ts} +0 -0
- /package/dist/src/{views/flow/nodes/nodes.types.js → types/endpoint.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export { EventNode } from './src/publicComponents/event-node';
|
|
2
2
|
export { ApiNode } from './src/publicComponents/api-node';
|
|
3
3
|
export { NoopNode } from './src/publicComponents/noop-node';
|
|
4
|
-
export { BaseNode } from './src/publicComponents/base-node';
|
|
5
|
-
export { BaseHandle } from './src/publicComponents/base-handle';
|
|
4
|
+
export { BaseNode } from './src/publicComponents/base-node/base-node';
|
|
5
|
+
export { BaseHandle } from './src/publicComponents/base-node/base-handle';
|
|
6
6
|
export { Position } from '@xyflow/react';
|
|
7
|
-
export type { EventNodeData, ApiNodeData } from './src/
|
|
7
|
+
export type { EventNodeData, ApiNodeData } from './src/types/flow';
|
|
8
8
|
export type { ApiNodeProps, BaseNodeProps, CronNodeProps, EventNodeProps, NoopNodeProps, } from './src/publicComponents/node-props';
|
|
9
|
-
export { Button } from './src/components/ui/button';
|
package/dist/index.html
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
|
|
6
|
+
<link rel="icon" type="image/png" href="/icon.png" />
|
|
6
7
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
7
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
8
9
|
<link
|
|
9
|
-
href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
|
|
10
11
|
rel="stylesheet"
|
|
11
12
|
/>
|
|
12
13
|
<script src="https://cdn.amplitude.com/libs/analytics-browser-2.11.1-min.js.gz"></script>
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
</script>
|
|
24
25
|
|
|
25
26
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
26
|
-
<title>Motia</title>
|
|
27
|
+
<title>Motia Workbench</title>
|
|
27
28
|
</head>
|
|
28
29
|
<body class="dark">
|
|
29
30
|
<div id="root"></div>
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export { EventNode } from './src/publicComponents/event-node';
|
|
2
2
|
export { ApiNode } from './src/publicComponents/api-node';
|
|
3
3
|
export { NoopNode } from './src/publicComponents/noop-node';
|
|
4
|
-
export { BaseNode } from './src/publicComponents/base-node';
|
|
5
|
-
export { BaseHandle } from './src/publicComponents/base-handle';
|
|
4
|
+
export { BaseNode } from './src/publicComponents/base-node/base-node';
|
|
5
|
+
export { BaseHandle } from './src/publicComponents/base-node/base-handle';
|
|
6
6
|
export { Position } from '@xyflow/react';
|
|
7
|
-
export { Button } from './src/components/ui/button';
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/src/App.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CollapsiblePanel, CollapsiblePanelGroup, TabsContent, TabsList, TabsTrigger } from '@motiadev/ui';
|
|
3
|
+
import { ReactFlowProvider } from '@xyflow/react';
|
|
4
|
+
import { File, GanttChart, Link2, LogsIcon } from 'lucide-react';
|
|
5
|
+
import { EndpointsPage } from './components/endpoints/endpoints-page';
|
|
6
|
+
import { FlowPage } from './components/flow/flow-page';
|
|
7
|
+
import { FlowTabMenuItem } from './components/flow/flow-tab-menu-item';
|
|
8
|
+
import { Header } from './components/header/header';
|
|
9
|
+
import { LogsPage } from './components/logs/logs-page';
|
|
10
|
+
import { TracesPage } from './components/observability/traces-page';
|
|
11
|
+
import { APP_SIDEBAR_CONTAINER_ID } from './components/sidebar/sidebar';
|
|
12
|
+
import { StatesPage } from './components/states/states-page';
|
|
13
|
+
import { useTabsStore } from './stores/use-tabs-store';
|
|
14
|
+
export const App = () => {
|
|
15
|
+
const tab = useTabsStore((state) => state.tab);
|
|
16
|
+
const setTopTab = useTabsStore((state) => state.setTopTab);
|
|
17
|
+
const setBottomTab = useTabsStore((state) => state.setBottomTab);
|
|
18
|
+
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: setTopTab, header: _jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "flow", children: _jsx(FlowTabMenuItem, {}) }), _jsxs(TabsTrigger, { value: "endpoint", 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: setBottomTab, header: _jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "tracing", children: [_jsx(GanttChart, {}), " Tracing"] }), _jsxs(TabsTrigger, { value: "logs", children: [_jsx(LogsIcon, {}), "Logs"] }), _jsxs(TabsTrigger, { value: "states", 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 })] }));
|
|
19
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
|
-
variant?: "POST" | "GET" | "
|
|
4
|
+
variant?: "POST" | "GET" | "DELETE" | "PUT" | "PATCH" | "HEAD" | "OPTIONS" | null | undefined;
|
|
5
5
|
defaultVariants?: "variant" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cva } from 'class-variance-authority';
|
|
3
3
|
import { cn } from '@/lib/utils';
|
|
4
|
-
const badgeVariants = cva('
|
|
4
|
+
const badgeVariants = cva('rounded-lg px-2 py-1 text-sm font-mono font-bold transition-colors', {
|
|
5
5
|
variants: {
|
|
6
6
|
variant: {
|
|
7
|
-
POST: 'bg-
|
|
8
|
-
GET: 'bg-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
PATCH: 'bg-yellow-500/50 text-yellow-100',
|
|
12
|
-
HEAD: 'bg-blue-500/50 text-blue-100',
|
|
13
|
-
OPTIONS: 'bg-purple-500/50 text-purple-100',
|
|
7
|
+
POST: 'bg-[#258DC3]/15 text-[#258DC3]',
|
|
8
|
+
GET: 'bg-[#709A2D]/15 text-[#709A2D]',
|
|
9
|
+
DELETE: 'bg-[#DE2134]/15 text-[#DE2134]',
|
|
10
|
+
PUT: 'bg-yellow-500/50 text-yellow-100', // TODO color
|
|
11
|
+
PATCH: 'bg-yellow-500/50 text-yellow-100', // TODO color
|
|
12
|
+
HEAD: 'bg-blue-500/50 text-blue-100', // TODO color
|
|
13
|
+
OPTIONS: 'bg-purple-500/50 text-purple-100', // TODO color
|
|
14
14
|
},
|
|
15
15
|
defaultVariants: {
|
|
16
16
|
variant: 'bg-blue-500/50 text-blue-100',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { ApiEndpoint } from '@/types/endpoint';
|
|
2
|
+
import { FC } from 'react';
|
|
3
3
|
type Props = {
|
|
4
4
|
endpoint: ApiEndpoint;
|
|
5
5
|
onClose: () => void;
|
|
6
6
|
};
|
|
7
|
-
export declare const EndpointCall:
|
|
7
|
+
export declare const EndpointCall: FC<Props>;
|
|
8
8
|
export {};
|
|
@@ -1,49 +1,46 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Sidebar } from '@/components/sidebar/sidebar';
|
|
3
|
+
import { Button, Input, Panel } from '@motiadev/ui';
|
|
3
4
|
import { Loader2, Play, X } from 'lucide-react';
|
|
4
|
-
import {
|
|
5
|
-
import { Input } from '../ui/input';
|
|
6
|
-
import { Textarea } from '../ui/textarea';
|
|
5
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
7
6
|
import { EndpointBadge } from './endpoint-badge';
|
|
7
|
+
import { EndpointResponse } from './endpoint-response';
|
|
8
|
+
import { EndpointResponseSchema } from './endpoint-response-schema';
|
|
8
9
|
import { useJsonSchemaToJson } from './hooks/use-json-schema-to-json';
|
|
9
10
|
import { usePathParams } from './hooks/use-path-params';
|
|
10
|
-
import {
|
|
11
|
+
import { JsonEditor } from './json-editor';
|
|
11
12
|
export const EndpointCall = ({ endpoint, onClose }) => {
|
|
12
13
|
const shouldHaveBody = ['post', 'put', 'patch'].includes(endpoint.method.toLowerCase());
|
|
13
14
|
const [isRequestLoading, setIsRequestLoading] = useState(false);
|
|
14
|
-
const [responseCode, setResponseCode] = useState();
|
|
15
|
-
const [responseBody, setResponseBody] = useState();
|
|
16
|
-
const [executionTime, setExecutionTime] = useState();
|
|
15
|
+
const [responseCode, setResponseCode] = useState(undefined);
|
|
16
|
+
const [responseBody, setResponseBody] = useState(undefined);
|
|
17
|
+
const [executionTime, setExecutionTime] = useState(undefined);
|
|
17
18
|
const { body, setBody } = useJsonSchemaToJson(endpoint.bodySchema);
|
|
18
|
-
const [
|
|
19
|
+
const [isBodyValid, setIsBodyValid] = useState(true);
|
|
19
20
|
const pathParams = usePathParams(endpoint.path);
|
|
20
21
|
const [pathParamsValues, setPathParamsValues] = useState(pathParams?.reduce((acc, param) => ({ ...acc, [param]: '' }), {}));
|
|
21
22
|
const [queryParamsValues, setQueryParamsValues] = useState(endpoint.queryParams?.reduce((acc, param) => ({ ...acc, [param.name]: '' }), {}) ?? {});
|
|
22
|
-
const { data: responseBodyData, isStreamed } = useStateStream(responseBody);
|
|
23
23
|
const isPlayEnabled = useMemo(() => {
|
|
24
24
|
if (!pathParams)
|
|
25
25
|
return true;
|
|
26
|
-
if (shouldHaveBody && !
|
|
26
|
+
if (shouldHaveBody && !isBodyValid)
|
|
27
27
|
return false;
|
|
28
28
|
return pathParams?.every((param) => pathParamsValues[param]);
|
|
29
|
-
}, [pathParams, pathParamsValues, shouldHaveBody,
|
|
29
|
+
}, [pathParams, pathParamsValues, shouldHaveBody, isBodyValid]);
|
|
30
30
|
const onPathParamChange = (param, value) => {
|
|
31
31
|
setPathParamsValues((prev) => ({ ...prev, [param]: value }));
|
|
32
32
|
};
|
|
33
33
|
const onQueryParamChange = (param, value) => {
|
|
34
34
|
setQueryParamsValues((prev) => ({ ...prev, [param]: value }));
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (endpoint.id) {
|
|
38
|
+
setResponseCode(undefined);
|
|
39
|
+
setResponseBody(undefined);
|
|
40
|
+
setExecutionTime(undefined);
|
|
41
|
+
setIsRequestLoading(false);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
setIsJsonValid(false);
|
|
45
|
-
}
|
|
46
|
-
}, [setBody]);
|
|
43
|
+
}, [endpoint.id]);
|
|
47
44
|
const handleRequest = async () => {
|
|
48
45
|
setIsRequestLoading(true);
|
|
49
46
|
const startTime = Date.now();
|
|
@@ -67,5 +64,13 @@ export const EndpointCall = ({ endpoint, onClose }) => {
|
|
|
67
64
|
setExecutionTime(executionTime);
|
|
68
65
|
setIsRequestLoading(false);
|
|
69
66
|
};
|
|
70
|
-
return (_jsxs(
|
|
67
|
+
return (_jsxs(Sidebar, { initialWidth: 600, title: _jsxs("div", { className: "flex flex-row gap-2 items-center", children: [_jsx(EndpointBadge, { variant: endpoint.method, children: endpoint.method.toUpperCase() }), _jsx("span", { className: "text-md font-bold", children: endpoint.path })] }), onClose: onClose, actions: [
|
|
68
|
+
{
|
|
69
|
+
icon: _jsx(X, { className: "cursor-pointer w-4 h-4", onClick: onClose }),
|
|
70
|
+
onClick: onClose,
|
|
71
|
+
},
|
|
72
|
+
], children: [endpoint.description && (_jsx("div", { className: "rounded-lg border p-4 font-medium text-muted-foreground", children: endpoint.description })), !!pathParams.length && (_jsx(Panel, { title: "Path params", size: "sm", children: _jsx("table", { children: pathParams.map((param) => (_jsxs("tr", { children: [_jsx("td", { className: "flex flex-col font-bold leading-[36px]", children: param }), _jsx("td", { className: "w-2/3 pl-4", children: _jsx(Input, { className: "w-full", value: pathParamsValues[param], onChange: (e) => onPathParamChange(param, e.target.value) }) })] }, param))) }) })), !!endpoint.queryParams?.length && (_jsx(Panel, { title: "Query params", size: "sm", children: _jsx("table", { children: endpoint.queryParams.map((param) => (_jsxs("tr", { children: [_jsxs("td", { className: "flex flex-col", children: [_jsx("span", { className: "font-bold", children: param.name }), _jsx("span", { className: "text-md text-muted-foreground", children: param.description })] }), _jsx("td", { className: "w-2/3 pl-4", children: _jsx(Input, { className: "w-full", value: queryParamsValues[param.name], onChange: (e) => onQueryParamChange(param.name, e.target.value) }) })] }, param.name))) }) })), shouldHaveBody && (_jsx(Panel, { title: "Body", size: "sm", contentClassName: "p-0", children: _jsx(JsonEditor, { value: body, schema: endpoint.bodySchema, 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 }), _jsx(EndpointResponseSchema, { items: Object.entries(endpoint?.responseSchema ?? {}).map(([status, schema]) => ({
|
|
73
|
+
responseCode: status,
|
|
74
|
+
bodySchema: schema,
|
|
75
|
+
})) })] }));
|
|
71
76
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
export type EndpointResponseItem = {
|
|
3
|
+
responseCode: string;
|
|
4
|
+
bodySchema: Record<string, Record<string, any>>;
|
|
5
|
+
};
|
|
6
|
+
type EndpointResponseProps = {
|
|
7
|
+
items: EndpointResponseItem[];
|
|
8
|
+
};
|
|
9
|
+
export declare const EndpointResponseSchema: FC<EndpointResponseProps>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { convertJsonSchemaToJson } from '@/components/endpoints/hooks/utils';
|
|
3
|
+
import { useThemeStore } from '@/stores/use-theme-store';
|
|
4
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@motiadev/ui';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
import ReactJson from 'react18-json-view';
|
|
7
|
+
const EndpointResponseSchemaItem = ({ responseCode, bodySchema }) => {
|
|
8
|
+
const theme = useThemeStore((store) => store.theme);
|
|
9
|
+
const schema = useMemo(() => convertJsonSchemaToJson(bodySchema), [bodySchema]);
|
|
10
|
+
return (_jsx(TabsContent, { value: responseCode, className: "border-t", children: _jsx("div", { className: "text-xs font-mono rounded-lg whitespace-pre-wrap", children: _jsx(ReactJson, { src: schema, dark: theme === 'dark', enableClipboard: false, style: { backgroundColor: 'transparent' } }) }) }, responseCode));
|
|
11
|
+
};
|
|
12
|
+
export const EndpointResponseSchema = ({ items }) => {
|
|
13
|
+
if (items.length === 0) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return (_jsx("div", { className: "flex flex-col rounded-lg border", "data-testid": "endpoint-response-container", children: _jsxs(Tabs, { defaultValue: items[0].responseCode, children: [_jsx("div", { className: "flex items-center justify-between bg-card", children: _jsx(TabsList, { className: "bg-transparent p-0", children: items.map((item) => (_jsx(TabsTrigger, { value: item.responseCode, className: "text-xs font-bold cursor-pointer", children: item.responseCode }, item.responseCode))) }) }), items.map((props) => (_jsx(EndpointResponseSchemaItem, { ...props }, props.responseCode)))] }) }));
|
|
17
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
type EndpointResponseProps = {
|
|
3
|
+
responseCode: number | string | undefined;
|
|
4
|
+
responseBody: Record<string, any> | undefined;
|
|
5
|
+
executionTime?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const EndpointResponse: FC<EndpointResponseProps>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useStateStream } from '@/components/endpoints/hooks/use-state-stream';
|
|
3
|
+
import { useThemeStore } from '@/stores/use-theme-store';
|
|
4
|
+
import { Panel } from '@motiadev/ui';
|
|
5
|
+
import { XCircle } from 'lucide-react';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import ReactJson from 'react18-json-view';
|
|
8
|
+
const getStatusMessage = (status) => {
|
|
9
|
+
switch (status) {
|
|
10
|
+
case 200:
|
|
11
|
+
return 'OK';
|
|
12
|
+
case 201:
|
|
13
|
+
return 'Created';
|
|
14
|
+
case 204:
|
|
15
|
+
return 'No Content';
|
|
16
|
+
case 400:
|
|
17
|
+
return 'Bad Request';
|
|
18
|
+
case 401:
|
|
19
|
+
return 'Unauthorized';
|
|
20
|
+
case 403:
|
|
21
|
+
return 'Forbidden';
|
|
22
|
+
case 404:
|
|
23
|
+
return 'Not Found';
|
|
24
|
+
case 500:
|
|
25
|
+
return 'Internal Server Error';
|
|
26
|
+
default:
|
|
27
|
+
return 'Unknown Status';
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export const EndpointResponse = ({ responseCode, executionTime, responseBody }) => {
|
|
31
|
+
const theme = useThemeStore((state) => state.theme);
|
|
32
|
+
const { data, isStreamed } = useStateStream(responseBody);
|
|
33
|
+
const statusMessage = useMemo(() => getStatusMessage(Number(responseCode)), [responseCode]);
|
|
34
|
+
const isError = Number(responseCode) >= 400;
|
|
35
|
+
if (!responseBody || !responseCode) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return (_jsx(Panel, { title: _jsxs("div", { className: "flex flex-row justify-between items-center flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [isError && _jsx(XCircle, { className: "text-red-500 w-4 h-4" }), _jsxs("span", { className: "font-bold text-xs", children: [responseCode, " - ", statusMessage] })] }), !!executionTime && (_jsxs("span", { className: "text-xs text-muted-foreground justify-self-end", children: ["Execution time: ", _jsxs("span", { className: "font-bold", children: [executionTime, "ms"] })] }))] }), subtitle: isStreamed && (_jsxs("span", { className: "col-span-2 flex flex-row items-center font-medium text-card-foreground text-xs mt-2", children: [_jsxs("span", { className: "inline-block w-2 h-2 rounded-full bg-green-500 mr-2 relative", children: [_jsx("span", { className: "absolute inset-0 rounded-full bg-green-500 animate-[ping_1.5s_ease-in-out_infinite]" }), _jsx("span", { className: "absolute inset-0 rounded-full bg-green-500" })] }), "Object is being streamed, this is not the actual response from the API Endpoint"] })), children: _jsx(ReactJson, { src: data, dark: theme === 'dark', enableClipboard: false, style: { backgroundColor: 'transparent' } }) }));
|
|
39
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import { useGlobalStore } from '@/stores/use-global-store';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { EndpointBadge } from './endpoint-badge';
|
|
6
|
+
import { EndpointCall } from './endpoint-call';
|
|
7
|
+
import { useGetEndpoints } from './hooks/use-get-endpoints';
|
|
8
|
+
export const EndpointsPage = () => {
|
|
9
|
+
const endpoints = useGetEndpoints();
|
|
10
|
+
const selectedEndpointId = useGlobalStore((state) => state.selectedEndpointId);
|
|
11
|
+
const selectEndpointId = useGlobalStore((state) => state.selectEndpointId);
|
|
12
|
+
const selectedEndpoint = useMemo(() => selectedEndpointId && endpoints.find((endpoint) => endpoint.id === selectedEndpointId), [endpoints, selectedEndpointId]);
|
|
13
|
+
return (_jsxs("div", { className: "flex flex-row w-full h-full", children: [_jsx("div", { className: "flex flex-col flex-1 overflow-y-auto", children: endpoints.map((endpoint) => (_jsx("div", { "data-testid": `endpoint-${endpoint.method}-${endpoint.path}`, className: cn(selectedEndpoint === endpoint && 'bg-muted-foreground/10', 'cursor-pointer select-none'), onClick: () => selectEndpointId(endpoint.id), children: _jsxs("div", { className: "flex flex-row gap-2 items-center hover:bg-muted-foreground/10 p-2", children: [_jsx(EndpointBadge, { variant: endpoint.method, children: endpoint.method.toUpperCase() }), _jsx("span", { className: "text-md font-mono font-bold whitespace-nowrap", children: endpoint.path }), _jsx("span", { className: "text-md text-muted-foreground truncate", children: endpoint.description })] }) }, `${endpoint.method} ${endpoint.path}`))) }), selectedEndpoint && _jsx(EndpointCall, { endpoint: selectedEndpoint, onClose: () => selectEndpointId(undefined) })] }));
|
|
14
|
+
};
|
|
@@ -1,16 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
type QueryParam = {
|
|
3
|
-
name: string;
|
|
4
|
-
description: string;
|
|
5
|
-
};
|
|
6
|
-
export type ApiEndpoint = {
|
|
7
|
-
id: string;
|
|
8
|
-
method: ApiRouteMethod;
|
|
9
|
-
path: string;
|
|
10
|
-
description?: string;
|
|
11
|
-
queryParams?: QueryParam[];
|
|
12
|
-
responseSchema?: Record<string, any>;
|
|
13
|
-
bodySchema?: Record<string, Record<string, any>>;
|
|
14
|
-
};
|
|
1
|
+
import { ApiEndpoint } from '@/types/endpoint';
|
|
15
2
|
export declare const useGetEndpoints: () => ApiEndpoint[];
|
|
16
|
-
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
type JsonEditorProps = {
|
|
3
|
+
value: string;
|
|
4
|
+
schema: Record<string, unknown> | undefined;
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
onValidate: (isValid: boolean) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const JsonEditor: FC<JsonEditorProps>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo } from 'react';
|
|
3
|
+
import Editor, { useMonaco } from '@monaco-editor/react';
|
|
4
|
+
import { useThemeStore } from '@/stores/use-theme-store';
|
|
5
|
+
export const JsonEditor = ({ value, schema, onChange, onValidate }) => {
|
|
6
|
+
const monaco = useMonaco();
|
|
7
|
+
const theme = useThemeStore((state) => state.theme);
|
|
8
|
+
const editorTheme = useMemo(() => (theme === 'dark' ? 'vs-dark' : 'light'), [theme]);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!monaco || !schema)
|
|
11
|
+
return;
|
|
12
|
+
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
|
13
|
+
validate: true,
|
|
14
|
+
schemas: [
|
|
15
|
+
{
|
|
16
|
+
uri: window.location.href,
|
|
17
|
+
fileMatch: ['*'],
|
|
18
|
+
schema,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
}, [monaco, schema]);
|
|
23
|
+
return (_jsx(Editor, { height: "200px", language: "json", value: value, theme: editorTheme, onChange: (value) => {
|
|
24
|
+
onChange(value ?? '');
|
|
25
|
+
}, onValidate: (markers) => {
|
|
26
|
+
onValidate(markers.length === 0);
|
|
27
|
+
}, options: {
|
|
28
|
+
lineNumbers: 'off',
|
|
29
|
+
minimap: { enabled: false },
|
|
30
|
+
} }));
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FlowPage: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useFlowStore } from '@/stores/use-flow-store';
|
|
3
|
+
import { useStreamItem } from '@motiadev/stream-client-react';
|
|
4
|
+
import { FlowView } from './flow-view';
|
|
5
|
+
export const FlowPage = () => {
|
|
6
|
+
const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
|
|
7
|
+
const { data: flow } = useStreamItem({
|
|
8
|
+
streamName: '__motia.flows',
|
|
9
|
+
groupId: 'default',
|
|
10
|
+
id: selectedFlowId ?? '',
|
|
11
|
+
});
|
|
12
|
+
const { data: flowConfig } = useStreamItem({
|
|
13
|
+
streamName: '__motia.flowsConfig',
|
|
14
|
+
groupId: 'default',
|
|
15
|
+
id: selectedFlowId ?? '',
|
|
16
|
+
});
|
|
17
|
+
if (!flow || flow.error)
|
|
18
|
+
return (_jsx("div", { className: "w-full h-full bg-background flex flex-col items-center justify-center", children: _jsx("p", { children: flow?.error }) }));
|
|
19
|
+
return _jsx(FlowView, { flow: flow, flowConfig: flowConfig });
|
|
20
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FlowTabMenuItem: () => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@motiadev/ui';
|
|
3
|
+
import { ChevronsUpDown, Workflow } from 'lucide-react';
|
|
4
|
+
import { useFlowStore } from '@/stores/use-flow-store';
|
|
5
|
+
import { useFetchFlows } from '@/hooks/use-fetch-flows';
|
|
6
|
+
export const FlowTabMenuItem = () => {
|
|
7
|
+
useFetchFlows();
|
|
8
|
+
const selectFlowId = useFlowStore((state) => state.selectFlowId);
|
|
9
|
+
const flows = useFlowStore((state) => state.flows);
|
|
10
|
+
const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
|
|
11
|
+
if (flows.length === 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("div", { className: "flex flex-row justify-center items-center gap-2 cursor-pointer", children: [_jsx(Workflow, {}), selectedFlowId ?? 'No flow selected', _jsx(ChevronsUpDown, { className: "size-4" })] }) }), _jsx(DropdownMenuContent, { className: "bg-background text-foreground", children: flows.map((item) => (_jsx(DropdownMenuItem, { className: "cursor-pointer gap-2", onClick: () => selectFlowId(item), children: item }, `dropdown-${item}`))) })] }));
|
|
15
|
+
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
|
|
1
2
|
import { Edge as ReactFlowEdge, Node as ReactFlowNode } from '@xyflow/react';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import { EdgeData, NodeData } from './nodes/nodes.types';
|
|
4
|
-
import { FlowConfigResponse, FlowResponse } from './hooks/use-get-flow-state';
|
|
5
4
|
import '@xyflow/react/dist/style.css';
|
|
6
5
|
export type FlowNode = ReactFlowNode<NodeData>;
|
|
7
6
|
export type FlowEdge = ReactFlowEdge<EdgeData>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Background, BackgroundVariant, ReactFlow, } from '@xyflow/react';
|
|
3
|
+
import { useCallback, useState } from 'react';
|
|
4
|
+
import { BaseEdge } from './base-edge';
|
|
5
|
+
import { FlowLoader } from './flow-loader';
|
|
6
|
+
import { useGetFlowState } from './hooks/use-get-flow-state';
|
|
7
|
+
import { NodeOrganizer } from './node-organizer';
|
|
8
|
+
import '@xyflow/react/dist/style.css';
|
|
9
|
+
const edgeTypes = {
|
|
10
|
+
base: BaseEdge,
|
|
11
|
+
};
|
|
12
|
+
export const FlowView = ({ flow, flowConfig }) => {
|
|
13
|
+
const { nodes, edges, onNodesChange, onEdgesChange, nodeTypes } = useGetFlowState(flow, flowConfig);
|
|
14
|
+
const [initialized, setInitialized] = useState(false);
|
|
15
|
+
const onInitialized = useCallback(() => setInitialized(true), []);
|
|
16
|
+
const onNodesChangeHandler = useCallback((changes) => onNodesChange(changes), [onNodesChange]);
|
|
17
|
+
if (!nodeTypes) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return (_jsxs("div", { className: "w-full h-full relative", children: [!initialized && _jsx(FlowLoader, {}), _jsxs(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodesChange: onNodesChangeHandler, onEdgesChange: onEdgesChange, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 50, size: 2, className: "[--xy-background-color-dots:theme(colors.muted.DEFAULT)] [--xy-background-color:theme(colors.background)]" }), _jsx(NodeOrganizer, { onInitialized: onInitialized })] })] }));
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
|
|
2
|
+
import { Edge, Node } from '@xyflow/react';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export declare const useGetFlowState: (flow: FlowResponse, flowConfig: FlowConfigResponse) => {
|
|
5
|
+
nodes: Node<NodeData>[];
|
|
6
|
+
edges: Edge<EdgeData>[];
|
|
7
|
+
onNodesChange: import("@xyflow/react").OnNodesChange<Node<NodeData>>;
|
|
8
|
+
onEdgesChange: import("@xyflow/react").OnEdgesChange<Edge<EdgeData>>;
|
|
9
|
+
nodeTypes: Record<string, React.ComponentType<any>>;
|
|
10
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useEdgesState, useNodesState } from '@xyflow/react';
|
|
2
|
-
import
|
|
2
|
+
import isEqual from 'fast-deep-equal';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
4
|
import { ApiFlowNode } from '../nodes/api-flow-node';
|
|
4
|
-
import {
|
|
5
|
+
import { CronFlowNode } from '../nodes/cron-flow-node';
|
|
5
6
|
import { EventFlowNode } from '../nodes/event-flow-node';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
const DEFAULT_POSITION = { x: 0, y: 0 };
|
|
7
|
+
import { NoopFlowNode } from '../nodes/noop-flow-node';
|
|
8
|
+
import { useSaveWorkflowConfig } from './use-save-workflow-config';
|
|
9
|
+
const DEFAULT_CONFIG = { x: 0, y: 0 };
|
|
10
10
|
const getNodePosition = (flowConfig, stepName) => {
|
|
11
|
-
return flowConfig?.config[stepName] ||
|
|
11
|
+
return flowConfig?.config[stepName] || DEFAULT_CONFIG;
|
|
12
12
|
};
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
14
|
const nodeComponentCache = new Map();
|
|
@@ -17,7 +17,7 @@ const BASE_NODE_TYPES = {
|
|
|
17
17
|
event: EventFlowNode,
|
|
18
18
|
api: ApiFlowNode,
|
|
19
19
|
noop: NoopFlowNode,
|
|
20
|
-
cron:
|
|
20
|
+
cron: CronFlowNode,
|
|
21
21
|
};
|
|
22
22
|
async function importFlow(flow, flowConfig) {
|
|
23
23
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -46,8 +46,8 @@ async function importFlow(flow, flowConfig) {
|
|
|
46
46
|
id: step.id,
|
|
47
47
|
type: step.nodeComponentPath || step.type,
|
|
48
48
|
filePath: step.filePath,
|
|
49
|
-
position: step.filePath ? getNodePosition(flowConfig, step.filePath) :
|
|
50
|
-
data: step,
|
|
49
|
+
position: step.filePath ? getNodePosition(flowConfig, step.filePath) : DEFAULT_CONFIG,
|
|
50
|
+
data: { ...step, nodeConfig: step.filePath ? getNodePosition(flowConfig, step.filePath) : DEFAULT_CONFIG },
|
|
51
51
|
language: step.language,
|
|
52
52
|
}));
|
|
53
53
|
const edges = flow.edges.map((edge) => ({
|
|
@@ -102,10 +102,17 @@ export const useGetFlowState = (flow, flowConfig) => {
|
|
|
102
102
|
x: Math.round(node.position.x),
|
|
103
103
|
y: Math.round(node.position.y),
|
|
104
104
|
};
|
|
105
|
+
if (node.data.nodeConfig?.sourceHandlePosition) {
|
|
106
|
+
acc[node.data.filePath].sourceHandlePosition = node.data.nodeConfig.sourceHandlePosition;
|
|
107
|
+
}
|
|
108
|
+
if (node.data.nodeConfig?.targetHandlePosition) {
|
|
109
|
+
acc[node.data.filePath].targetHandlePosition = node.data.nodeConfig.targetHandlePosition;
|
|
110
|
+
}
|
|
105
111
|
}
|
|
106
112
|
return acc;
|
|
107
113
|
}, {});
|
|
108
114
|
if (!isEqual(steps, lastSavedConfigRef.current)) {
|
|
115
|
+
console.log('steps', steps, lastSavedConfigRef.current);
|
|
109
116
|
lastSavedConfigRef.current = steps;
|
|
110
117
|
const newConfig = { id: flowIdRef.current, config: steps };
|
|
111
118
|
try {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import { ApiNodeData, EdgeData, EventNodeData } from '@/types/flow';
|
|
1
2
|
import { Edge, Node } from '@xyflow/react';
|
|
2
|
-
import { EventNodeData, EdgeData, ApiNodeData } from '../nodes/nodes.types';
|
|
3
3
|
export declare const useOrganizeNodes: (nodes: Node<EventNodeData | ApiNodeData>[], edges: Edge<EdgeData>[], setNodes: (nodes: Node<EventNodeData | ApiNodeData>[]) => void) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { FlowConfigResponse } from '@/
|
|
1
|
+
import { FlowConfigResponse } from '@/types/flow';
|
|
2
2
|
export declare const useSaveWorkflowConfig: () => (body: FlowConfigResponse) => Promise<any>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { EventNodeProps } from '
|
|
1
|
+
import { EventNodeProps } from '@/publicComponents/node-props';
|
|
2
2
|
export declare const EventFlowNode: ({ data }: EventNodeProps) => import("react/jsx-runtime").JSX.Element;
|