@motiadev/workbench 0.2.1-beta.76 → 0.2.2-build.20250618141055
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 +1 -1
- package/dist/index.html +9 -9
- package/dist/index.js +1 -1
- package/dist/src/components/app-sidebar.js +2 -2
- package/dist/src/components/endpoints/endpoint-call.js +2 -2
- package/dist/src/components/header/header.js +1 -1
- package/dist/src/components/logs/log-console.js +1 -1
- package/dist/src/components/observability/events/code/function-call.d.ts +13 -0
- package/dist/src/components/observability/events/code/function-call.js +16 -0
- package/dist/src/components/observability/events/event-icon.d.ts +7 -0
- package/dist/src/components/observability/events/event-icon.js +16 -0
- package/dist/src/components/observability/events/trace-emit-event.d.ts +5 -0
- package/dist/src/components/observability/events/trace-emit-event.js +5 -0
- package/dist/src/components/observability/events/trace-event.d.ts +5 -0
- package/dist/src/components/observability/events/trace-event.js +20 -0
- package/dist/src/components/observability/events/trace-log-event.d.ts +5 -0
- package/dist/src/components/observability/events/trace-log-event.js +5 -0
- package/dist/src/components/observability/events/trace-state-event.d.ts +5 -0
- package/dist/src/components/observability/events/trace-state-event.js +5 -0
- package/dist/src/components/observability/events/trace-stream-event.d.ts +5 -0
- package/dist/src/components/observability/events/trace-stream-event.js +5 -0
- package/dist/src/components/observability/hooks/use-get-endtime.d.ts +2 -0
- package/dist/src/components/observability/hooks/use-get-endtime.js +15 -0
- package/dist/src/components/observability/observability-stats.d.ts +5 -0
- package/dist/src/components/observability/observability-stats.js +17 -0
- package/dist/src/components/observability/trace-item/trace-item-detail.d.ts +7 -0
- package/dist/src/components/observability/trace-item/trace-item-detail.js +10 -0
- package/dist/src/components/observability/trace-item/trace-item.d.ts +9 -0
- package/dist/src/components/observability/trace-item/trace-item.js +20 -0
- package/dist/src/components/observability/trace-status.d.ts +12 -0
- package/dist/src/components/observability/trace-status.js +43 -0
- package/dist/src/components/observability/trace-timeline.d.ts +6 -0
- package/dist/src/components/observability/trace-timeline.js +17 -0
- package/dist/src/components/observability/traces-groups.d.ts +9 -0
- package/dist/src/components/observability/traces-groups.js +15 -0
- package/dist/src/components/ui/card.d.ts +8 -0
- package/dist/src/components/ui/card.js +16 -0
- package/dist/src/components/ui/navigation-menu.d.ts +9 -10
- package/dist/src/components/ui/navigation-menu.js +9 -10
- package/dist/src/components/ui/scroll-area.d.ts +5 -0
- package/dist/src/components/ui/scroll-area.js +9 -0
- package/dist/src/components/ui/sheet.d.ts +1 -1
- package/dist/src/components/ui/sidebar.js +1 -1
- package/dist/src/components/ui/tabs.d.ts +7 -0
- package/dist/src/components/ui/tabs.js +12 -0
- package/dist/src/hooks/use-fetch-flows.d.ts +5 -0
- package/dist/src/hooks/use-fetch-flows.js +17 -0
- package/dist/src/hooks/use-list-flows.d.ts +3 -2
- package/dist/src/index.css +2 -155
- package/dist/src/lib/utils.d.ts +1 -0
- package/dist/src/lib/utils.js +7 -0
- package/dist/src/main.js +2 -1
- package/dist/src/routes/flow.js +2 -13
- package/dist/src/routes/index.js +2 -2
- package/dist/src/routes/traces-page.d.ts +1 -0
- package/dist/src/routes/traces-page.js +14 -0
- package/dist/src/types/observability.d.ts +78 -0
- package/dist/src/types/observability.js +1 -0
- package/dist/src/views/flow/flow-view.js +2 -17
- package/dist/src/views/flow/hooks/use-get-flow-state.d.ts +5 -2
- package/dist/src/views/flow/hooks/use-get-flow-state.js +97 -27
- package/dist/src/views/flow/hooks/use-save-workflow-config.d.ts +2 -9
- package/dist/src/views/flow/hooks/use-save-workflow-config.js +5 -6
- package/dist/src/views/flow/legend.js +1 -1
- package/dist/src/views/flow/node-organizer.js +4 -2
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/package.json +12 -6
- package/dist/src/components/ui/button.d.ts +0 -11
- package/dist/src/components/ui/button.js +0 -33
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export { BaseHandle } from './src/publicComponents/base-handle';
|
|
|
6
6
|
export { Position } from '@xyflow/react';
|
|
7
7
|
export type { EventNodeData, ApiNodeData } from './src/views/flow/nodes/nodes.types';
|
|
8
8
|
export type { ApiNodeProps, BaseNodeProps, CronNodeProps, EventNodeProps, NoopNodeProps, } from './src/publicComponents/node-props';
|
|
9
|
-
export { Button } from '
|
|
9
|
+
export { Button } from '@motiadev/ui';
|
package/dist/index.html
CHANGED
|
@@ -6,20 +6,20 @@
|
|
|
6
6
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
7
7
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
8
8
|
<link
|
|
9
|
-
href="https://fonts.googleapis.com/css2?family=
|
|
9
|
+
href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
|
|
10
10
|
rel="stylesheet"
|
|
11
11
|
/>
|
|
12
12
|
<script src="https://cdn.amplitude.com/libs/analytics-browser-2.11.1-min.js.gz"></script>
|
|
13
13
|
<script>
|
|
14
14
|
window.amplitude.init('ab2408031a38aa5cb85587a27ecfc69c', {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
autocapture: {
|
|
16
|
+
fileDownloads: false,
|
|
17
|
+
formInteractions: false,
|
|
18
|
+
},
|
|
19
|
+
fetchRemoteConfig: true,
|
|
20
|
+
recording: false,
|
|
21
|
+
optOut: true,
|
|
22
|
+
})
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,4 @@ export { NoopNode } from './src/publicComponents/noop-node';
|
|
|
4
4
|
export { BaseNode } from './src/publicComponents/base-node';
|
|
5
5
|
export { BaseHandle } from './src/publicComponents/base-handle';
|
|
6
6
|
export { Position } from '@xyflow/react';
|
|
7
|
-
export { Button } from '
|
|
7
|
+
export { Button } from '@motiadev/ui';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useListFlows } from '@/hooks/use-list-flows';
|
|
3
|
-
import { File, Link2, Logs, Workflow } from 'lucide-react';
|
|
3
|
+
import { File, Link2, Logs, Workflow, GanttChartIcon } from 'lucide-react';
|
|
4
4
|
import { Link, useLocation } from 'react-router';
|
|
5
5
|
import { Sidebar, SidebarButton, SidebarGroup } from './ui/sidebar';
|
|
6
6
|
import { BadgeCount } from './ui/BadgeCount';
|
|
@@ -8,5 +8,5 @@ export const AppSidebar = () => {
|
|
|
8
8
|
const { flows } = useListFlows();
|
|
9
9
|
const { pathname } = useLocation();
|
|
10
10
|
const isActive = (flowId) => pathname.includes(`/flow/${flowId}`);
|
|
11
|
-
return (_jsxs(Sidebar, { children: [_jsxs(SidebarGroup, { testId: "motia-title", title: "Motia", children: [_jsx(Link, { "data-testid": "logs-link", to: "/logs", children: _jsxs(SidebarButton, { isActive: pathname === '/logs', icon: _jsx(Logs, { className: "w-4 h-4" }), children: ["Logs", pathname !== '/logs' && _jsx(BadgeCount, {})] }) }), _jsx(Link, { "data-testid": "states-link", to: "/states", children: _jsx(SidebarButton, { isActive: pathname === '/states', icon: _jsx(File, { className: "w-4 h-4" }), children: "States" }) }), _jsx(Link, { "data-testid": "endpoints-link", to: "/endpoints", children: _jsx(SidebarButton, { isActive: pathname === '/endpoints', icon: _jsx(Link2, { className: "w-4 h-4" }), children: "Endpoints" }) })] }), _jsx(SidebarGroup, { testId: "flows-title", title: "Flows", children: flows.map((flow) => (_jsx(Link, { "data-testid": `flow-${flow.name}-link`, to: `/flow/${flow.id}`, children: _jsx(SidebarButton, { isActive: isActive(flow.id), icon: _jsx(Workflow, { className: "w-4 h-4" }), children: flow.name }) }, flow.id))) })] }));
|
|
11
|
+
return (_jsxs(Sidebar, { children: [_jsxs(SidebarGroup, { testId: "motia-title", title: "Motia", children: [_jsx(Link, { "data-testid": "logs-link", to: "/logs", children: _jsxs(SidebarButton, { isActive: pathname === '/logs', icon: _jsx(Logs, { className: "w-4 h-4" }), children: ["Logs", pathname !== '/logs' && _jsx(BadgeCount, {})] }) }), _jsx(Link, { "data-testid": "traces-link", to: "/traces", children: _jsx(SidebarButton, { isActive: pathname === '/traces', icon: _jsx(GanttChartIcon, { className: "w-4 h-4" }), children: "Traces" }) }), _jsx(Link, { "data-testid": "states-link", to: "/states", children: _jsx(SidebarButton, { isActive: pathname === '/states', icon: _jsx(File, { className: "w-4 h-4" }), children: "States" }) }), _jsx(Link, { "data-testid": "endpoints-link", to: "/endpoints", children: _jsx(SidebarButton, { isActive: pathname === '/endpoints', icon: _jsx(Link2, { className: "w-4 h-4" }), children: "Endpoints" }) })] }), _jsx(SidebarGroup, { testId: "flows-title", title: "Flows", children: flows.map((flow) => (_jsx(Link, { "data-testid": `flow-${flow.name}-link`, to: `/flow/${flow.id}`, children: _jsx(SidebarButton, { isActive: isActive(flow.id), icon: _jsx(Workflow, { className: "w-4 h-4" }), children: flow.name }) }, flow.id))) })] }));
|
|
12
12
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useMemo, useState } from 'react';
|
|
3
3
|
import { Loader2, Play, X } from 'lucide-react';
|
|
4
|
-
import { Button } from '
|
|
4
|
+
import { Button } from '@motiadev/ui';
|
|
5
5
|
import { Input } from '../ui/input';
|
|
6
6
|
import { Textarea } from '../ui/textarea';
|
|
7
7
|
import { EndpointBadge } from './endpoint-badge';
|
|
@@ -67,5 +67,5 @@ export const EndpointCall = ({ endpoint, onClose }) => {
|
|
|
67
67
|
setExecutionTime(executionTime);
|
|
68
68
|
setIsRequestLoading(false);
|
|
69
69
|
};
|
|
70
|
-
return (_jsxs("div", { className: "flex flex-col gap-2 overflow-y-auto", children: [_jsxs("div", { className: "text-xs flex flex-row gap-2 items-center justify-between w-full", children: [_jsx("span", { className: "font-bold", children: "Request" }), _jsx("div", { className: "flex flex-row gap-2 items-center hover:bg-white/10 rounded-md p-1", children: _jsx(X, { className: "cursor-pointer w-4 h-4", onClick: onClose }) })] }), _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 })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: endpoint.description }), !!pathParams.length && (_jsxs("div", { className: "flex flex-col gap-2 p-4 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Path Params" }), _jsx("div", { className: "flex flex-col gap-4", children: pathParams.map((param) => (_jsxs("div", { className: "text-xs", children: [_jsx("div", { className: "font-bold mb-2", children: param }), _jsx(Input, { className: "w-full", value: pathParamsValues[param], onChange: (e) => onPathParamChange(param, e.target.value) })] }, param))) })] })), !!endpoint.queryParams?.length && (_jsxs("div", { className: "flex flex-col gap-2 p-4 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Query Params" }), _jsx("div", { className: "flex flex-col gap-4", children: endpoint.queryParams.map((param) => (_jsxs("div", { className: "text-xs", children: [_jsx("div", { className: "font-bold mb-2", children: param.name }), _jsx(Input, { className: "w-full", value: queryParamsValues[param.name], onChange: (e) => onQueryParamChange(param.name, e.target.value) })] }, param.name))) })] })), shouldHaveBody && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Body" }), _jsx(Textarea, { "data-testid": "endpoint-body-textarea", className: `w-full font-mono font-medium min-h-[200px] ${!isJsonValid ? 'border-red-500' : ''}`, value: body, onChange: handleBodyChange }), _jsx("span", { "data-testid": "endpoint-invalid-json-message", className: `text-xs text-red-500 ${isJsonValid ? 'invisible' : ''}`, children: "Invalid JSON" })] })), _jsxs(Button, { className: "w-fit", onClick: handleRequest, "data-testid": "endpoint-play-button", disabled: isRequestLoading || !isPlayEnabled, children: [isRequestLoading ? _jsx(Loader2, { className: "animate-spin" }) : _jsx(Play, {}), " Play"] }), responseCode !== undefined && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-muted", "data-testid": "endpoint-response-container", children: [_jsxs("span", { className: "text-xs font-bold", children: [_jsx(EndpointBadge, { variant: responseCode >= 400 ? 'DELETE' : 'GET', children: responseCode }), " Execution time: ", _jsxs("span", { className: "text-muted-foreground", children: [executionTime, "ms"] })] }), isStreamed && (_jsxs("span", { className: "flex flex-row items-center font-medium text-muted-foreground text-xs", children: [_jsxs("span", { className: "ml-1 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"] })), _jsx("span", { className: "text-xs font-mono font-bold dark:bg-black/50 bg-white/50 p-2 rounded-lg whitespace-pre-wrap", children: JSON.stringify(responseBodyData, null, 2) })] }))] }));
|
|
70
|
+
return (_jsxs("div", { className: "flex flex-col gap-2 overflow-y-auto", children: [_jsxs("div", { className: "text-xs flex flex-row gap-2 items-center justify-between w-full", children: [_jsx("span", { className: "font-bold", children: "Request" }), _jsx("div", { className: "flex flex-row gap-2 items-center hover:bg-white/10 rounded-md p-1", children: _jsx(X, { className: "cursor-pointer w-4 h-4", onClick: onClose }) })] }), _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 })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: endpoint.description }), !!pathParams.length && (_jsxs("div", { className: "flex flex-col gap-2 p-4 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Path Params" }), _jsx("div", { className: "flex flex-col gap-4", children: pathParams.map((param) => (_jsxs("div", { className: "text-xs", children: [_jsx("div", { className: "font-bold mb-2", children: param }), _jsx(Input, { className: "w-full", value: pathParamsValues[param], onChange: (e) => onPathParamChange(param, e.target.value) })] }, param))) })] })), !!endpoint.queryParams?.length && (_jsxs("div", { className: "flex flex-col gap-2 p-4 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Query Params" }), _jsx("div", { className: "flex flex-col gap-4", children: endpoint.queryParams.map((param) => (_jsxs("div", { className: "text-xs", children: [_jsx("div", { className: "font-bold mb-2", children: param.name }), _jsx(Input, { className: "w-full", value: queryParamsValues[param.name], onChange: (e) => onQueryParamChange(param.name, e.target.value) })] }, param.name))) })] })), shouldHaveBody && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-muted", children: [_jsx("span", { className: "text-xs font-bold", children: "Body" }), _jsx(Textarea, { "data-testid": "endpoint-body-textarea", className: `w-full font-mono font-medium min-h-[200px] ${!isJsonValid ? 'border-red-500' : ''}`, value: body, onChange: handleBodyChange }), _jsx("span", { "data-testid": "endpoint-invalid-json-message", className: `text-xs text-red-500 ${isJsonValid ? 'invisible' : ''}`, children: "Invalid JSON" })] })), _jsxs(Button, { className: "w-fit", onClick: handleRequest, "data-testid": "endpoint-play-button", disabled: isRequestLoading || !isPlayEnabled, children: [isRequestLoading ? _jsx(Loader2, { className: "animate-spin w-4 h-4" }) : _jsx(Play, { className: "w-4 h-4" }), " Play"] }), responseCode !== undefined && (_jsxs("div", { className: "flex flex-col gap-2 rounded-lg bg-muted", "data-testid": "endpoint-response-container", children: [_jsxs("span", { className: "text-xs font-bold", children: [_jsx(EndpointBadge, { variant: responseCode >= 400 ? 'DELETE' : 'GET', children: responseCode }), " Execution time: ", _jsxs("span", { className: "text-muted-foreground", children: [executionTime, "ms"] })] }), isStreamed && (_jsxs("span", { className: "flex flex-row items-center font-medium text-muted-foreground text-xs", children: [_jsxs("span", { className: "ml-1 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"] })), _jsx("span", { className: "text-xs font-mono font-bold dark:bg-black/50 bg-white/50 p-2 rounded-lg whitespace-pre-wrap", children: JSON.stringify(responseBodyData, null, 2) })] }))] }));
|
|
71
71
|
};
|
|
@@ -11,5 +11,5 @@ export const Header = () => {
|
|
|
11
11
|
const { pathname } = useLocation();
|
|
12
12
|
const { flows } = useListFlows();
|
|
13
13
|
const isActive = (flowId) => pathname.includes(`/flow/${flowId}`);
|
|
14
|
-
return (_jsxs("header", { className: "min-h-16 px-4 gap-1 flex items-center bg-header text-header-foreground border-b border-header-border", children: [_jsx(LogoIcon, { className: "h-8 w-8 mr-16" }), _jsx(NavigationMenu, { children: _jsxs(NavigationMenuList, { children: [_jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { asChild: true,
|
|
14
|
+
return (_jsxs("header", { className: "min-h-16 px-4 gap-1 flex items-center bg-header text-header-foreground border-b border-header-border", children: [_jsx(LogoIcon, { className: "h-8 w-8 mr-16" }), _jsx(NavigationMenu, { children: _jsxs(NavigationMenuList, { children: [_jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { asChild: true, children: _jsxs(Link, { "data-testid": "header-logs-link", to: "/logs", className: 'flex flex-row items-center pr-2 relative', children: ["Logs", _jsx(BadgeCount, { className: "absolute top-1 right-0", dotOnly: true })] }) }) }), _jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { "data-testid": "header-traces-link", to: "/traces", children: "Traces" }) }) }), _jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { "data-testid": "header-states-link", to: "/states", children: "States" }) }) }), _jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { "data-testid": "header-endpoints-link", to: "/endpoints", children: "Endpoints" }) }) })] }) }), _jsx(NavigationMenu, { children: _jsxs(NavigationMenuList, { children: [_jsxs(NavigationMenuItem, { children: [_jsx(NavigationMenuTrigger, { className: 'cursor-pointer', "data-testid": "header-flows-link", children: "Flows" }), _jsx(NavigationMenuContent, { children: _jsx(NavigationMenuSub, { children: _jsx(NavigationMenuList, { className: "flex flex-col min-w-[200px]", children: flows.map((flow) => (_jsx(NavigationMenuItem, { className: "w-full", asChild: true, children: _jsx(NavigationMenuLink, { asChild: true, active: isActive(flow.id), children: _jsxs(Link, { "data-testid": `flow-${flow.name}-link`, to: `/flow/${flow.id}`, className: 'flex flex-row gap-2 items-center', children: [_jsx(Workflow, { className: "w-4 h-4" }), " ", flow.name] }) }) }, flow.id))) }) }) })] }), _jsx(NavigationMenuIndicator, {})] }) }), _jsx("div", { className: "ml-auto", children: _jsx(ThemeToggle, {}) })] }));
|
|
15
15
|
};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useLogs } from '@/stores/use-logs';
|
|
3
3
|
import { ChevronDown, ChevronUp, Trash2 } from 'lucide-react';
|
|
4
4
|
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
5
|
-
import { Button } from '
|
|
5
|
+
import { Button } from '@motiadev/ui';
|
|
6
6
|
import { cn } from '@/lib/utils';
|
|
7
7
|
import { Logs } from './logs';
|
|
8
8
|
const MIN_HEIGHT = 100;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
topLevelClassName?: string;
|
|
4
|
+
objectName?: string;
|
|
5
|
+
functionName: string;
|
|
6
|
+
args: Array<string | object | false | undefined>;
|
|
7
|
+
callsQuantity?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const Argument: React.FC<{
|
|
10
|
+
arg: string | object | false;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const FunctionCall: React.FC<Props>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
export const Argument = ({ arg }) => {
|
|
3
|
+
if (typeof arg === 'string') {
|
|
4
|
+
return _jsxs("span", { className: "font-mono text-blue-500", children: ["'", arg, "'"] });
|
|
5
|
+
}
|
|
6
|
+
else if (arg === false) {
|
|
7
|
+
return _jsx("span", { className: "font-mono text-blue-100 font-bold bg-blue-500/50 px-2 rounded-md", children: "value" });
|
|
8
|
+
}
|
|
9
|
+
const entries = Object.entries(arg);
|
|
10
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-green-500", children: '{ ' }), entries.map(([key, value], index) => (_jsxs("span", { children: [key, ": ", _jsx(Argument, { arg: value }), index < entries.length - 1 && _jsx(_Fragment, { children: ", " })] }, key))), _jsx("span", { className: "font-mono text-green-500", children: ' }' })] }));
|
|
11
|
+
};
|
|
12
|
+
export const FunctionCall = ({ topLevelClassName, objectName, functionName, args, callsQuantity }) => {
|
|
13
|
+
const hasCalls = callsQuantity && callsQuantity > 1;
|
|
14
|
+
const filteredArgs = args.filter((arg) => arg !== undefined);
|
|
15
|
+
return (_jsxs("div", { children: [topLevelClassName && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-pink-500", children: topLevelClassName }), "."] })), objectName && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-pink-500", children: objectName }), "."] })), _jsx("span", { className: "font-mono text-pink-500", children: functionName }), _jsx("span", { className: "font-mono text-emerald-500", children: "(" }), filteredArgs.map((arg, index) => (_jsxs("span", { children: [_jsx(Argument, { arg: arg }), index < filteredArgs.length - 1 && _jsx(_Fragment, { children: ", " })] }, index))), _jsx("span", { className: "font-mono text-emerald-500", children: ")" }), hasCalls && _jsxs("span", { className: "font-mono text-muted-foreground", children: [" x", callsQuantity] })] }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MessageCircle, Package, Radio, ScrollText } from 'lucide-react';
|
|
3
|
+
export const EventIcon = ({ event }) => {
|
|
4
|
+
if (event.type === 'log') {
|
|
5
|
+
return _jsx(ScrollText, { className: "w-4 h-4 text-muted-foreground" });
|
|
6
|
+
}
|
|
7
|
+
else if (event.type === 'emit') {
|
|
8
|
+
return _jsx(MessageCircle, { className: "w-4 h-4 text-muted-foreground" });
|
|
9
|
+
}
|
|
10
|
+
else if (event.type === 'state') {
|
|
11
|
+
return _jsx(Package, { className: "w-4 h-4 text-muted-foreground" });
|
|
12
|
+
}
|
|
13
|
+
else if (event.type === 'stream') {
|
|
14
|
+
return _jsx(Radio, { className: "w-4 h-4 text-muted-foreground" });
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { TraceEmitEvent } from './trace-emit-event';
|
|
4
|
+
import { TraceLogEvent } from './trace-log-event';
|
|
5
|
+
import { TraceStateEvent } from './trace-state-event';
|
|
6
|
+
import { TraceStreamEvent } from './trace-stream-event';
|
|
7
|
+
export const TraceEvent = memo(({ event }) => {
|
|
8
|
+
if (event.type === 'log') {
|
|
9
|
+
return _jsx(TraceLogEvent, { event: event });
|
|
10
|
+
}
|
|
11
|
+
else if (event.type === 'emit') {
|
|
12
|
+
return _jsx(TraceEmitEvent, { event: event });
|
|
13
|
+
}
|
|
14
|
+
else if (event.type === 'state') {
|
|
15
|
+
return _jsx(TraceStateEvent, { event: event });
|
|
16
|
+
}
|
|
17
|
+
else if (event.type === 'stream') {
|
|
18
|
+
return _jsx(TraceStreamEvent, { event: event });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { LogLevelBadge } from '@/components/logs/log-level-badge';
|
|
3
|
+
export const TraceLogEvent = ({ event }) => {
|
|
4
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(LogLevelBadge, { level: event.level }), " ", event.message] }));
|
|
5
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FunctionCall } from './code/function-call';
|
|
3
|
+
export const TraceStateEvent = ({ event }) => {
|
|
4
|
+
return (_jsx(FunctionCall, { objectName: "state", functionName: event.operation, args: [event.data.traceId, event.data.key, event.data.value ? false : undefined] }));
|
|
5
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FunctionCall } from './code/function-call';
|
|
3
|
+
export const TraceStreamEvent = ({ event }) => {
|
|
4
|
+
return (_jsx(FunctionCall, { topLevelClassName: "streams", objectName: event.streamName, functionName: event.operation, args: [event.data.groupId, event.data.id, event.data.data ? false : undefined], callsQuantity: event.calls }));
|
|
5
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
export const useGetEndTime = (group) => {
|
|
3
|
+
const groupEndTime = group?.endTime;
|
|
4
|
+
const [endTime, setEndTime] = useState(groupEndTime || Date.now());
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (groupEndTime) {
|
|
7
|
+
setEndTime(groupEndTime);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
const interval = setInterval(() => setEndTime(Date.now()), 50);
|
|
11
|
+
return () => clearInterval(interval);
|
|
12
|
+
}
|
|
13
|
+
}, [groupEndTime]);
|
|
14
|
+
return endTime;
|
|
15
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
4
|
+
import { Activity, CheckCircle, Hash, XCircle } from 'lucide-react';
|
|
5
|
+
const calculateStats = (groups) => {
|
|
6
|
+
const running = groups.filter(({ status }) => status === 'running').length;
|
|
7
|
+
const completed = groups.filter(({ status }) => status === 'completed').length;
|
|
8
|
+
const failed = groups.filter(({ status }) => status === 'failed').length;
|
|
9
|
+
return { total: groups.length, running, completed, failed };
|
|
10
|
+
};
|
|
11
|
+
const Stat = ({ title, value, icon }) => {
|
|
12
|
+
return (_jsx(Card, { children: _jsxs(CardHeader, { className: "relative", children: [_jsx(CardDescription, { children: title }), _jsxs("div", { className: "flex flex-row gap-2 items-center", children: [icon, _jsx(CardTitle, { className: "@[250px]/card:text-3xl text-2xl font-semibold tabular-nums", children: value })] })] }) }));
|
|
13
|
+
};
|
|
14
|
+
export const ObservabilityStats = memo(({ groups }) => {
|
|
15
|
+
const stats = calculateStats(groups);
|
|
16
|
+
return (_jsxs("div", { className: "flex items-center gap-4", children: [_jsx(Stat, { title: "Total Traces", value: stats.total.toLocaleString(), icon: _jsx(Hash, { className: "w-4 h-4 text-teal-500" }) }), _jsx(Stat, { title: "Running Traces", value: stats.running.toLocaleString(), icon: _jsx(Activity, { className: "w-4 h-4 text-blue-500" }) }), _jsx(Stat, { title: "Completed Traces", value: stats.completed.toLocaleString(), icon: _jsx(CheckCircle, { className: "w-4 h-4 text-green-500" }) }), _jsx(Stat, { title: "Failed Traces", value: stats.failed.toLocaleString(), icon: _jsx(XCircle, { className: "w-4 h-4 text-red-500" }) })] }));
|
|
17
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from '@/components/ui/badge';
|
|
3
|
+
import { Card, CardContent } from '@/components/ui/card';
|
|
4
|
+
import { cn, formatDuration } from '@/lib/utils';
|
|
5
|
+
import { memo } from 'react';
|
|
6
|
+
import { EventIcon } from '../events/event-icon';
|
|
7
|
+
import { TraceEvent } from '../events/trace-event';
|
|
8
|
+
export const TraceItemDetail = memo(({ trace }) => {
|
|
9
|
+
return (_jsxs(Card, { className: cn('mt-2', trace.error && 'border-red-800/80 border-solid'), children: [_jsxs(CardContent, { className: "p-4", children: [_jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground mb-4", children: [trace.endTime && _jsxs("span", { children: ["Duration: ", formatDuration(trace.endTime - trace.startTime)] }), _jsx("div", { className: "bg-blue-500 font-bold text-xs px-[4px] py-[2px] rounded-sm text-blue-100", children: trace.entryPoint.type }), trace.correlationId && _jsxs(Badge, { variant: "outline", children: ["Correlated: ", trace.correlationId] })] }), _jsx("div", { className: "pl-6 border-l-1 border-gray-500/40 font-mono text-xs flex flex-col gap-3", children: trace.events.map((event, index) => (_jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute -left-[26px] top-[8px] w-1 h-1 rounded-full bg-emerald-500 outline outline-2 outline-emerald-500/50" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(EventIcon, { event: event }), _jsxs("span", { className: "text-sm font-mono text-muted-foreground", children: ["+", Math.floor(event.timestamp - trace.startTime), "ms"] }), _jsx(TraceEvent, { event: event })] })] }, index))) })] }), trace.error && (_jsxs("div", { className: "p-4 bg-red-800/10", children: [_jsx("div", { className: "text-sm text-red-800 dark:text-red-400 font-semibold", children: trace.error.message }), _jsx("div", { className: "text-sm text-red-800 dark:text-red-400 pl-4", children: trace.error.stack })] }))] }));
|
|
10
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import { ChevronDown } from 'lucide-react';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { TraceItemDetail } from './trace-item-detail';
|
|
6
|
+
export const TraceItem = ({ trace, group, groupEndTime }) => {
|
|
7
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
8
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "flex flex-row items-center hover:bg-muted/50 p-1 rounded-md cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [_jsxs("div", { className: "flex items-center min-w-[200px] w-[200px] h-[20px]", children: [_jsx(ChevronDown, { className: cn('w-[20px] h-4 mr-2 transition-transform duration-50', {
|
|
9
|
+
'rotate-180': isExpanded,
|
|
10
|
+
}) }), _jsx("h2", { className: "text-sm font-medium text-muted-foreground", children: trace.name })] }), _jsx("div", { className: "relative w-full", children: _jsx("div", { className: cn('h-[20px] rounded-[4px] cursor-pointer hover:opacity-80 transition-all duration-200', {
|
|
11
|
+
'bg-blue-500': trace.status === 'running',
|
|
12
|
+
'bg-green-500': trace.status === 'completed',
|
|
13
|
+
'bg-red-500': trace.status === 'failed',
|
|
14
|
+
}), onClick: () => setIsExpanded(!isExpanded), style: {
|
|
15
|
+
marginLeft: `${((trace.startTime - group.startTime) / (groupEndTime - group.startTime)) * 100}%`,
|
|
16
|
+
width: trace.endTime
|
|
17
|
+
? `${((trace.endTime - trace.startTime) / (groupEndTime - group.startTime)) * 100}%`
|
|
18
|
+
: `${((Date.now() - trace.startTime) / (groupEndTime - group.startTime)) * 100}%`,
|
|
19
|
+
} }) })] }), isExpanded && _jsx(TraceItemDetail, { trace: trace })] }));
|
|
20
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TraceGroup } from '../../types/observability';
|
|
3
|
+
export declare const LoadingSpinner: React.FC<{
|
|
4
|
+
className: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const TraceStatus: React.FC<{
|
|
7
|
+
status: TraceGroup['status'];
|
|
8
|
+
name: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const TraceStatusBadge: React.FC<{
|
|
11
|
+
status: TraceGroup['status'];
|
|
12
|
+
}>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
import { CheckCircle, Clock, XCircle } from 'lucide-react';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
export const LoadingSpinner = ({ className }) => {
|
|
6
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: cn('animate-spin', className), children: _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
|
|
7
|
+
};
|
|
8
|
+
const getStatusIcon = (status) => {
|
|
9
|
+
switch (status) {
|
|
10
|
+
case 'running':
|
|
11
|
+
case 'active':
|
|
12
|
+
return _jsx(LoadingSpinner, { className: "w-4 h-4 text-blue-500" });
|
|
13
|
+
case 'completed':
|
|
14
|
+
return _jsx(CheckCircle, { className: "w-4 h-4 text-green-500" });
|
|
15
|
+
case 'failed':
|
|
16
|
+
return _jsx(XCircle, { className: "w-4 h-4 text-red-500" });
|
|
17
|
+
case 'stalled':
|
|
18
|
+
return _jsx(Clock, { className: "w-4 h-4 text-yellow-500" });
|
|
19
|
+
default:
|
|
20
|
+
return _jsx(Clock, { className: "w-4 h-4 text-gray-500" });
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const statusVariants = cva('inline-flex items-center rounded-lg px-3 py-[2px] uppercase text-[10px] font-bold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', {
|
|
24
|
+
variants: {
|
|
25
|
+
status: {
|
|
26
|
+
running: 'dark:bg-blue-800/30 dark:text-blue-500 bg-blue-100 text-blue-700',
|
|
27
|
+
active: 'dark:bg-blue-800/30 dark:text-blue-500 bg-blue-100 text-blue-700',
|
|
28
|
+
completed: 'dark:bg-green-800/30 dark:text-green-500 bg-green-100 text-green-700',
|
|
29
|
+
failed: 'dark:bg-red-800/30 dark:text-red-500 bg-red-100 text-red-700',
|
|
30
|
+
stalled: 'dark:bg-yellow-800/30 dark:text-yellow-500 bg-yellow-100 text-yellow-700',
|
|
31
|
+
default: 'dark:bg-gray-800/30 dark:text-gray-500 bg-gray-100 text-gray-800',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
status: 'default',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
export const TraceStatus = ({ status, name }) => {
|
|
39
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [getStatusIcon(status), _jsx("span", { className: "font-medium text-sm", children: name })] }));
|
|
40
|
+
};
|
|
41
|
+
export const TraceStatusBadge = ({ status }) => {
|
|
42
|
+
return _jsx("div", { className: statusVariants({ status }), children: status });
|
|
43
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { useStreamGroup, useStreamItem } from '@motiadev/stream-client-react';
|
|
4
|
+
import { TraceItem } from './trace-item/trace-item';
|
|
5
|
+
import { useGetEndTime } from './hooks/use-get-endtime';
|
|
6
|
+
export const TraceTimeline = memo(({ groupId }) => {
|
|
7
|
+
const { data: group } = useStreamItem({
|
|
8
|
+
streamName: 'motia-trace-group',
|
|
9
|
+
groupId: 'default',
|
|
10
|
+
id: groupId,
|
|
11
|
+
});
|
|
12
|
+
const { data } = useStreamGroup({ streamName: 'motia-trace', groupId });
|
|
13
|
+
const endTime = useGetEndTime(group);
|
|
14
|
+
if (!group)
|
|
15
|
+
return null;
|
|
16
|
+
return (_jsxs("div", { className: "flex flex-col p-2", children: [_jsxs("div", { className: "flex flex-row items-center px-2", children: [_jsx("div", { className: "flex items-center min-w-[200px] w-[200px] h-[20px]" }), _jsx("div", { className: "flex flex-1 relative", children: _jsxs("div", { className: "flex justify-between font-mono pb-2 w-full text-xs text-muted-foreground border-b border-blue-500", children: [_jsx("span", { children: "0ms" }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.25), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.5), "ms"] }), _jsxs("span", { children: [Math.floor((endTime - group.startTime) * 0.75), "ms"] }), _jsxs("span", { children: [Math.floor(endTime - group.startTime), "ms"] }), _jsxs("div", { className: "absolute bottom-[-4px] w-full flex justify-between", children: [_jsx("span", { className: "w-[1px] h-2 bg-blue-500" }), _jsx("span", { className: "w-[1px] h-2 bg-blue-500" }), _jsx("span", { className: "w-[1px] h-2 bg-blue-500" }), _jsx("span", { className: "w-[1px] h-2 bg-blue-500" }), _jsx("span", { className: "w-[1px] h-2 bg-blue-500" })] })] }) })] }), _jsx("div", { className: "h-full overflow-auto p-2 space-y-2", children: data?.map((trace) => _jsx(TraceItem, { trace: trace, group: group, groupEndTime: endTime }, trace.id)) })] }));
|
|
17
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TraceGroup } from '@/types/observability';
|
|
3
|
+
interface Props {
|
|
4
|
+
groups: TraceGroup[];
|
|
5
|
+
selectedGroupId: string | null;
|
|
6
|
+
onGroupSelect: (group: TraceGroup) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const TracesGroups: React.FC<Props>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Card, CardContent } from '@/components/ui/card';
|
|
4
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
5
|
+
import { TraceStatus, TraceStatusBadge } from './trace-status';
|
|
6
|
+
export const TracesGroups = memo(({ groups, selectedGroupId, onGroupSelect }) => {
|
|
7
|
+
const formatDuration = (duration) => {
|
|
8
|
+
if (!duration)
|
|
9
|
+
return 'N/A';
|
|
10
|
+
if (duration < 1000)
|
|
11
|
+
return `${duration}ms`;
|
|
12
|
+
return `${(duration / 1000).toFixed(1)}s`;
|
|
13
|
+
};
|
|
14
|
+
return (_jsxs("div", { className: "overflow-auto p-4 space-y-4 ", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-semibold", children: "Traces" }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [groups.length, " total"] })] }), groups.length > 0 && (_jsx("div", { className: "space-y-2", children: [...groups].reverse().map((group) => (_jsx(Card, { "data-testid": `trace-${group.id}`, className: `cursor-pointer transition-colors hover:bg-muted/50 ${selectedGroupId === group.id ? 'ring-2 ring-primary' : ''}`, onClick: () => onGroupSelect(group), children: _jsxs(CardContent, { className: "p-3", children: [_jsxs("div", { className: "flex flex-row justify-between mb-2", children: [_jsx(TraceStatus, { status: group.status, name: group.name }), _jsx(TraceStatusBadge, { status: group.status })] }), _jsxs("div", { className: "text-xs text-muted-foreground space-y-1", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("div", { "data-testid": "trace-id", className: "text-xs text-muted-foreground font-semibold font-mono tracking-[1px]", children: group.id }), _jsxs("span", { children: [group.metadata.totalSteps, " steps"] })] }), _jsxs("div", { className: "flex justify-between", children: [group.endTime && _jsxs("span", { children: ["Duration: ", formatDuration(group.endTime - group.startTime)] }), _jsxs("span", { children: [formatDistanceToNow(group.startTime), " ago"] })] }), group.metadata.activeSteps > 0 && (_jsxs("div", { className: "text-blue-600", children: [group.metadata.activeSteps, " active"] }))] })] }) }, group.id))) }))] }));
|
|
15
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
3
|
+
declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
4
|
+
declare const CardTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
5
|
+
declare const CardDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
6
|
+
declare const CardContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
const Card = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn('rounded-lg border bg-card text-card-foreground shadow-sm', className), ...props })));
|
|
5
|
+
Card.displayName = 'Card';
|
|
6
|
+
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn('flex flex-col space-y-1.5 p-4', className), ...props })));
|
|
7
|
+
CardHeader.displayName = 'CardHeader';
|
|
8
|
+
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx("h3", { ref: ref, className: cn('text-2xl font-semibold leading-none tracking-tight', className), ...props })));
|
|
9
|
+
CardTitle.displayName = 'CardTitle';
|
|
10
|
+
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx("p", { ref: ref, className: cn('text-sm text-muted-foreground', className), ...props })));
|
|
11
|
+
CardDescription.displayName = 'CardDescription';
|
|
12
|
+
const CardContent = React.forwardRef(({ className, ...props }, ref) => _jsx("div", { ref: ref, className: cn('p-6 pt-0', className), ...props }));
|
|
13
|
+
CardContent.displayName = 'CardContent';
|
|
14
|
+
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn('flex items-center p-6 pt-0', className), ...props })));
|
|
15
|
+
CardFooter.displayName = 'CardFooter';
|
|
16
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
|
|
3
|
-
declare function NavigationMenu({ className, children, viewport, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
|
|
3
|
+
export declare function NavigationMenu({ className, children, viewport, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
|
|
4
4
|
viewport?: boolean;
|
|
5
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
declare function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
declare function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
declare const navigationMenuTriggerStyle: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
9
|
-
declare function NavigationMenuTrigger({ className, children, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
declare function NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
-
declare function NavigationMenuViewport({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>): import("react/jsx-runtime").JSX.Element;
|
|
12
|
-
declare function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
declare function NavigationMenuIndicator({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle, };
|
|
6
|
+
export declare function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare const navigationMenuTriggerStyle: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
9
|
+
export declare function NavigationMenuTrigger({ className, children, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function NavigationMenuViewport({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function NavigationMenuIndicator({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,29 +3,28 @@ import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
|
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { ChevronDownIcon } from 'lucide-react';
|
|
5
5
|
import { cn } from '@/lib/utils';
|
|
6
|
-
function NavigationMenu({ className, children, viewport = true, ...props }) {
|
|
6
|
+
export function NavigationMenu({ className, children, viewport = true, ...props }) {
|
|
7
7
|
return (_jsxs(NavigationMenuPrimitive.Root, { "data-slot": "navigation-menu", "data-viewport": viewport, className: cn('group/navigation-menu relative flex max-w-max flex-1 items-center justify-center', className), ...props, children: [children, viewport && _jsx(NavigationMenuViewport, {})] }));
|
|
8
8
|
}
|
|
9
|
-
function NavigationMenuList({ className, ...props }) {
|
|
9
|
+
export function NavigationMenuList({ className, ...props }) {
|
|
10
10
|
return (_jsx(NavigationMenuPrimitive.List, { "data-slot": "navigation-menu-list", className: cn('group flex flex-1 list-none items-center justify-center gap-1', className), ...props }));
|
|
11
11
|
}
|
|
12
|
-
function NavigationMenuItem({ className, ...props }) {
|
|
12
|
+
export function NavigationMenuItem({ className, ...props }) {
|
|
13
13
|
return (_jsx(NavigationMenuPrimitive.Item, { "data-slot": "navigation-menu-item", className: cn('relative', className), ...props }));
|
|
14
14
|
}
|
|
15
|
-
const navigationMenuTriggerStyle = cva('group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1');
|
|
16
|
-
function NavigationMenuTrigger({ className, children, ...props }) {
|
|
15
|
+
export const navigationMenuTriggerStyle = cva('group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1');
|
|
16
|
+
export function NavigationMenuTrigger({ className, children, ...props }) {
|
|
17
17
|
return (_jsxs(NavigationMenuPrimitive.Trigger, { "data-slot": "navigation-menu-trigger", className: cn(navigationMenuTriggerStyle(), 'group', className), ...props, children: [children, ' ', _jsx(ChevronDownIcon, { className: "relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180", "aria-hidden": "true" })] }));
|
|
18
18
|
}
|
|
19
|
-
function NavigationMenuContent({ className, ...props }) {
|
|
19
|
+
export function NavigationMenuContent({ className, ...props }) {
|
|
20
20
|
return (_jsx(NavigationMenuPrimitive.Content, { "data-slot": "navigation-menu-content", className: cn('data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto', 'group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none', className), ...props }));
|
|
21
21
|
}
|
|
22
|
-
function NavigationMenuViewport({ className, ...props }) {
|
|
22
|
+
export function NavigationMenuViewport({ className, ...props }) {
|
|
23
23
|
return (_jsx("div", { className: cn('absolute top-full left-0 isolate z-50 flex justify-center'), children: _jsx(NavigationMenuPrimitive.Viewport, { "data-slot": "navigation-menu-viewport", className: cn('origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]', className), ...props }) }));
|
|
24
24
|
}
|
|
25
|
-
function NavigationMenuLink({ className, ...props }) {
|
|
25
|
+
export function NavigationMenuLink({ className, ...props }) {
|
|
26
26
|
return (_jsx(NavigationMenuPrimitive.Link, { "data-slot": "navigation-menu-link", className: cn("data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4", className), ...props }));
|
|
27
27
|
}
|
|
28
|
-
function NavigationMenuIndicator({ className, ...props }) {
|
|
28
|
+
export function NavigationMenuIndicator({ className, ...props }) {
|
|
29
29
|
return (_jsx(NavigationMenuPrimitive.Indicator, { "data-slot": "navigation-menu-indicator", className: cn('data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden', className), ...props, children: _jsx("div", { className: "bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" }) }));
|
|
30
30
|
}
|
|
31
|
-
export { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle, };
|