ai-design-system 0.1.67 → 0.1.69
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/components/{composites → blocks}/EvalSessionDetailsPanel/EvalSessionDetailsPanel.stories.tsx +1 -1
- package/components/{composites → blocks}/EvalSessionDetailsPanel/EvalSessionDetailsPanel.tsx +15 -5
- package/components/blocks/SectionLayout/interfaces.ts +1 -0
- package/components/blocks/WorkflowCanvas/interfaces.ts +2 -1
- package/components/blocks/index.ts +4 -0
- package/components/composites/AdjustableLayout/AdjustableLayout.tsx +13 -1
- package/components/composites/DataTable/EnhancedDataTable.tsx +6 -4
- package/components/composites/ProjectSwitcher/ProjectSwitcher.tsx +2 -2
- package/components/composites/index.ts +1 -3
- package/components/features/EvalDashboardFeature/EvalDashboardFeature.behaviors.stories.tsx +13 -6
- package/components/features/EvalDashboardFeature/EvalDashboardFeature.mocks.ts +30 -0
- package/components/features/EvalDashboardFeature/EvalDashboardFeature.stories.tsx +9 -2
- package/components/features/EvalDashboardFeature/EvalDashboardFeature.tsx +21 -16
- package/components/features/EvalDashboardFeature/useEvalDashboardFeature.d.ts +1 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +2 -2
- package/components/features/index.ts +4 -3
- package/dist/index.cjs +1164 -1149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +37 -50
- package/dist/index.js +1164 -1149
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- /package/components/{composites → blocks}/EvalSessionDetailsPanel/index.ts +0 -0
package/components/{composites → blocks}/EvalSessionDetailsPanel/EvalSessionDetailsPanel.stories.tsx
RENAMED
|
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react"
|
|
|
2
2
|
import { EvalSessionDetailsPanel } from "./EvalSessionDetailsPanel"
|
|
3
3
|
|
|
4
4
|
const meta = {
|
|
5
|
-
title: "
|
|
5
|
+
title: "Blocks/EvalSessionDetailsPanel",
|
|
6
6
|
component: EvalSessionDetailsPanel,
|
|
7
7
|
parameters: {
|
|
8
8
|
layout: "padded",
|
package/components/{composites → blocks}/EvalSessionDetailsPanel/EvalSessionDetailsPanel.tsx
RENAMED
|
@@ -18,12 +18,14 @@ export interface EvalSessionDetails {
|
|
|
18
18
|
export interface EvalSessionDetailsPanelProps {
|
|
19
19
|
sessionDetails: EvalSessionDetails
|
|
20
20
|
activeTab: string
|
|
21
|
+
actionHandlers?: { onTriggerEvaluation?: () => void }
|
|
22
|
+
workflowContent?: React.ReactNode
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
export const EvalTriggerButton = ({ onClick }: { onClick: () => void }) => (
|
|
24
|
-
<Button onClick={onClick} size="sm">
|
|
25
|
-
<Icon name=
|
|
26
|
-
Trigger
|
|
25
|
+
export const EvalTriggerButton = ({ onClick, loading }: { onClick: () => void; loading?: boolean }) => (
|
|
26
|
+
<Button onClick={onClick} variant="default" size="sm" className="h-8" disabled={loading}>
|
|
27
|
+
<Icon name={loading ? 'loader-2' : 'play'} className={`w-4 h-4 mr-2${loading ? ' animate-spin' : ''}`} />
|
|
28
|
+
{loading ? 'Evaluating...' : 'Trigger'}
|
|
27
29
|
</Button>
|
|
28
30
|
)
|
|
29
31
|
|
|
@@ -42,7 +44,7 @@ const goldenEvalTableSchema = dynamicTableSchema.parse({
|
|
|
42
44
|
})
|
|
43
45
|
|
|
44
46
|
export const EvalSessionDetailsPanel = React.memo<EvalSessionDetailsPanelProps>(
|
|
45
|
-
({ sessionDetails, activeTab }) => {
|
|
47
|
+
({ sessionDetails, activeTab, actionHandlers, workflowContent }) => {
|
|
46
48
|
return (
|
|
47
49
|
<div className="flex flex-col h-full bg-background">
|
|
48
50
|
<Tabs value={activeTab} className="flex-1 flex flex-col min-h-0">
|
|
@@ -79,6 +81,14 @@ export const EvalSessionDetailsPanel = React.memo<EvalSessionDetailsPanelProps>(
|
|
|
79
81
|
</div>
|
|
80
82
|
</ScrollArea>
|
|
81
83
|
</TabsContent>
|
|
84
|
+
|
|
85
|
+
<TabsContent value="workflow" className="absolute inset-0 m-0 p-0">
|
|
86
|
+
{workflowContent || (
|
|
87
|
+
<div className="flex items-center justify-center h-full text-muted-foreground">
|
|
88
|
+
No workflow data available.
|
|
89
|
+
</div>
|
|
90
|
+
)}
|
|
91
|
+
</TabsContent>
|
|
82
92
|
</div>
|
|
83
93
|
</Tabs>
|
|
84
94
|
</div>
|
|
@@ -2,8 +2,9 @@ import type { Connection, EdgeChange, Node, NodeChange, OnConnectStartParams } f
|
|
|
2
2
|
import type React from "react";
|
|
3
3
|
import type { StateNodeData } from "@/components/composites/StateNode";
|
|
4
4
|
import type { TransitionNodeData } from "@/components/composites/TransitionNode";
|
|
5
|
+
import type { TriggerNodeData } from "@/components/composites/TriggerNode";
|
|
5
6
|
|
|
6
|
-
export type WorkflowNodeData = StateNodeData | TransitionNodeData;
|
|
7
|
+
export type WorkflowNodeData = StateNodeData | TransitionNodeData | TriggerNodeData;
|
|
7
8
|
export type WorkflowNode = Node<WorkflowNodeData>;
|
|
8
9
|
|
|
9
10
|
export interface WorkflowEdge {
|
|
@@ -27,3 +27,7 @@ export type { FormReportsSectionProps } from './FormReportsSection'
|
|
|
27
27
|
|
|
28
28
|
export { InboxPanel } from './InboxPanel'
|
|
29
29
|
export type { InboxPanelProps } from './InboxPanel'
|
|
30
|
+
|
|
31
|
+
// EvalSessionDetailsPanel Block
|
|
32
|
+
export { EvalSessionDetailsPanel, EvalTriggerButton } from './EvalSessionDetailsPanel'
|
|
33
|
+
export type { EvalSessionDetailsPanelProps, EvalSessionDetails } from './EvalSessionDetailsPanel'
|
|
@@ -10,6 +10,7 @@ export interface AdjustableLayoutSection {
|
|
|
10
10
|
maxSize?: number // maximum percentage
|
|
11
11
|
resizable?: boolean // default true for >1 sections
|
|
12
12
|
className?: string
|
|
13
|
+
variant?: "default" | "ghost"
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export interface AdjustableLayoutProps extends React.ComponentPropsWithoutRef<"div"> {
|
|
@@ -66,6 +67,16 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
66
67
|
|
|
67
68
|
const [sizes, setSizes] = React.useState<number[]>(defaultSizes)
|
|
68
69
|
|
|
70
|
+
// Sync sizes if the number of sections changes (e.g. data loads and new section appears)
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
setSizes((prevSizes) => {
|
|
73
|
+
if (prevSizes.length !== sections.length) {
|
|
74
|
+
return defaultSizes;
|
|
75
|
+
}
|
|
76
|
+
return prevSizes;
|
|
77
|
+
});
|
|
78
|
+
}, [sections.length, defaultSizes])
|
|
79
|
+
|
|
69
80
|
// After hydration, overwrite with persisted sizes if available
|
|
70
81
|
React.useEffect(() => {
|
|
71
82
|
if (!storageKey) return
|
|
@@ -208,7 +219,8 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
208
219
|
<React.Fragment key={section.id}>
|
|
209
220
|
<div
|
|
210
221
|
className={cn(
|
|
211
|
-
"min-h-0 overflow-hidden
|
|
222
|
+
"min-h-0 overflow-hidden",
|
|
223
|
+
(section.variant ?? "default") === "default" && "bg-card border border-border rounded-xl",
|
|
212
224
|
section.className
|
|
213
225
|
)}
|
|
214
226
|
style={{
|
|
@@ -506,10 +506,12 @@ export function EnhancedDataTable({
|
|
|
506
506
|
))}
|
|
507
507
|
</DropdownMenuContent>
|
|
508
508
|
</DropdownMenu>
|
|
509
|
-
|
|
510
|
-
<
|
|
511
|
-
|
|
512
|
-
|
|
509
|
+
{onCreateClick && (
|
|
510
|
+
<Button variant="outline" size="sm" className="h-8" onClick={onCreateClick}>
|
|
511
|
+
<Icon name="plus" size="sm" />
|
|
512
|
+
<span>{createButtonLabel}</span>
|
|
513
|
+
</Button>
|
|
514
|
+
)}
|
|
513
515
|
{rightActions}
|
|
514
516
|
</div>
|
|
515
517
|
</div>
|
|
@@ -34,7 +34,7 @@ export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
|
34
34
|
({ projects, selectedProjectId, onSelectProject, onCreateProject, className }) => {
|
|
35
35
|
const [open, setOpen] = React.useState(false)
|
|
36
36
|
|
|
37
|
-
const selectedProject = projects.find((p) => p.id === selectedProjectId)
|
|
37
|
+
const selectedProject = projects.find((p) => String(p.id) === String(selectedProjectId))
|
|
38
38
|
const displayLabel = selectedProject ? selectedProject.name : "Select Project..."
|
|
39
39
|
|
|
40
40
|
const defaultValue = selectedProject ? `${selectedProject.name}-${selectedProject.id}` : undefined
|
|
@@ -86,7 +86,7 @@ export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
|
86
86
|
</div>
|
|
87
87
|
<Icon name="check"
|
|
88
88
|
className={`h-4 w-4 ${
|
|
89
|
-
selectedProjectId === project.id ? "opacity-100" : "opacity-0"
|
|
89
|
+
String(selectedProjectId) === String(project.id) ? "opacity-100" : "opacity-0"
|
|
90
90
|
}`}
|
|
91
91
|
/>
|
|
92
92
|
</CommandItem>
|
|
@@ -206,6 +206,4 @@ export type { SessionHeaderProps, ChatSessionInfo } from './SessionHeader'
|
|
|
206
206
|
export { AppBreadcrumb } from './AppBreadcrumb'
|
|
207
207
|
export type { AppBreadcrumbProps, BreadcrumbItemData } from './AppBreadcrumb'
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
export { EvalSessionDetailsPanel, EvalTriggerButton } from './EvalSessionDetailsPanel'
|
|
211
|
-
export type { EvalSessionDetailsPanelProps, EvalSessionDetails } from './EvalSessionDetailsPanel'
|
|
209
|
+
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import * as React from "react"
|
|
2
3
|
import { expect, within, userEvent, fn } from "@storybook/test"
|
|
3
4
|
import { EvalDashboardFeature } from "./EvalDashboardFeature"
|
|
4
|
-
import { evalDashboardFeatureStateMock } from "./EvalDashboardFeature.mocks"
|
|
5
|
+
import { evalDashboardFeatureStateMock, workflowMockNodes, workflowMockEdges } from "./EvalDashboardFeature.mocks"
|
|
6
|
+
import { NodeEditor } from "@/components/features/NodeEditor"
|
|
7
|
+
|
|
8
|
+
const workflowMock = (
|
|
9
|
+
<NodeEditor nodes={workflowMockNodes} edges={workflowMockEdges} showMinimap={false} interactive={false} />
|
|
10
|
+
)
|
|
5
11
|
|
|
6
12
|
const meta = {
|
|
7
13
|
title: "Features/EvalDashboardFeature/Behaviors",
|
|
@@ -25,16 +31,17 @@ export const Interactive: Story = {
|
|
|
25
31
|
actionHandlers: {
|
|
26
32
|
onTriggerEvaluation: fn(),
|
|
27
33
|
},
|
|
34
|
+
workflowContent: workflowMock,
|
|
28
35
|
},
|
|
29
36
|
play: async ({ canvasElement }) => {
|
|
30
37
|
const canvas = within(canvasElement)
|
|
31
38
|
|
|
32
|
-
//
|
|
39
|
+
// 4 tabs: Golden Evals, System Prompts, Outputs, Workflow
|
|
33
40
|
const tabs = await canvas.findAllByRole("tab")
|
|
34
|
-
expect(tabs.length).
|
|
41
|
+
expect(tabs.length).toBe(4)
|
|
35
42
|
|
|
36
|
-
// Switch to
|
|
37
|
-
const
|
|
38
|
-
await userEvent.click(
|
|
43
|
+
// Switch to Workflow tab
|
|
44
|
+
const workflowTab = canvas.getByRole("tab", { name: /Workflow/i })
|
|
45
|
+
await userEvent.click(workflowTab)
|
|
39
46
|
},
|
|
40
47
|
}
|
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
import type { UseEvalDashboardFeatureReturn } from "./useEvalDashboardFeature.d"
|
|
2
|
+
import type { WorkflowNode, WorkflowEdge } from "@/components/blocks/WorkflowCanvas"
|
|
3
|
+
|
|
4
|
+
export const workflowMockNodes: WorkflowNode[] = [
|
|
5
|
+
{ id: 'trigger-1', type: 'trigger', position: { x: 100, y: 20 }, data: { label: 'Agentic Eval', type: 'trigger', status: 'idle' } },
|
|
6
|
+
{ id: 'state-1', type: 'state', position: { x: 250, y: 20 }, data: { label: 'Initialize Eval', type: 'state', description: 'Parse session messages and config', status: 'idle' } },
|
|
7
|
+
{ id: 'transition-1', type: 'transition', position: { x: 400, y: 20 }, data: { label: 'Parse Session', type: 'transition', status: 'idle' } },
|
|
8
|
+
{ id: 'state-2', type: 'state', position: { x: 250, y: 140 }, data: { label: 'Fetch System Prompt', type: 'state', description: 'Load system prompt from session', status: 'idle' } },
|
|
9
|
+
{ id: 'transition-2', type: 'transition', position: { x: 400, y: 140 }, data: { label: 'Check Config', type: 'transition', description: 'Check if multi-agent config exists', status: 'idle' } },
|
|
10
|
+
{ id: 'state-2b', type: 'state', position: { x: 250, y: 260 }, data: { label: 'Fetch Config Prompt', type: 'state', description: 'Load agent config system prompt', status: 'idle' } },
|
|
11
|
+
{ id: 'transition-2b', type: 'transition', position: { x: 400, y: 260 }, data: { label: 'Format Prompt', type: 'transition', description: 'Build multi-agent system prompt', status: 'idle' } },
|
|
12
|
+
{ id: 'state-3', type: 'state', position: { x: 250, y: 380 }, data: { label: 'Build Messages', type: 'state', description: 'Construct LLM message payload', status: 'idle' } },
|
|
13
|
+
{ id: 'transition-3', type: 'transition', position: { x: 400, y: 380 }, data: { label: 'LLM Call', type: 'transition', status: 'idle' } },
|
|
14
|
+
{ id: 'state-4', type: 'state', position: { x: 250, y: 500 }, data: { label: 'Parse Eval', type: 'state', description: 'Parse LLM eval response', status: 'idle' } },
|
|
15
|
+
{ id: 'transition-4', type: 'transition', position: { x: 400, y: 500 }, data: { label: 'Persist', type: 'transition', status: 'idle' } },
|
|
16
|
+
{ id: 'state-5', type: 'state', position: { x: 250, y: 620 }, data: { label: 'Complete', type: 'state', description: 'Eval finished', status: 'idle', isTerminal: true } },
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
export const workflowMockEdges: WorkflowEdge[] = [
|
|
20
|
+
{ id: 'e-trigger-1', source: 'trigger-1', target: 'state-1' },
|
|
21
|
+
{ id: 'e-1-transition-1', source: 'state-1', target: 'transition-1' },
|
|
22
|
+
{ id: 'e-transition-1-2', source: 'transition-1', target: 'state-2' },
|
|
23
|
+
{ id: 'e-2-transition-2', source: 'state-2', target: 'transition-2' },
|
|
24
|
+
{ id: 'e-transition-2-2b', source: 'transition-2', target: 'state-2b' },
|
|
25
|
+
{ id: 'e-2b-transition-2b', source: 'state-2b', target: 'transition-2b' },
|
|
26
|
+
{ id: 'e-transition-2b-3', source: 'transition-2b', target: 'state-3' },
|
|
27
|
+
{ id: 'e-3-transition-3', source: 'state-3', target: 'transition-3' },
|
|
28
|
+
{ id: 'e-transition-3-4', source: 'transition-3', target: 'state-4' },
|
|
29
|
+
{ id: 'e-4-transition-4', source: 'state-4', target: 'transition-4' },
|
|
30
|
+
{ id: 'e-transition-4-5', source: 'transition-4', target: 'state-5' },
|
|
31
|
+
]
|
|
2
32
|
|
|
3
33
|
export const evalDashboardFeatureStateMock: UseEvalDashboardFeatureReturn = {
|
|
4
34
|
inbox: {
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import * as React from "react"
|
|
2
3
|
import { EvalDashboardFeature } from "./EvalDashboardFeature"
|
|
3
|
-
import { evalDashboardFeatureStateMock } from "./EvalDashboardFeature.mocks"
|
|
4
|
+
import { evalDashboardFeatureStateMock, workflowMockNodes, workflowMockEdges } from "./EvalDashboardFeature.mocks"
|
|
4
5
|
import { useEvalDashboardFeatureMock } from "./useEvalDashboardFeature.mock"
|
|
6
|
+
import { NodeEditor } from "@/components/features/NodeEditor"
|
|
7
|
+
|
|
8
|
+
const workflowMock = (
|
|
9
|
+
<NodeEditor nodes={workflowMockNodes} edges={workflowMockEdges} showMinimap={false} interactive={false} />
|
|
10
|
+
)
|
|
5
11
|
|
|
6
12
|
const meta = {
|
|
7
13
|
title: "Features/EvalDashboardFeature",
|
|
@@ -23,12 +29,13 @@ type Story = StoryObj<typeof meta>
|
|
|
23
29
|
export const Default: Story = {
|
|
24
30
|
args: {
|
|
25
31
|
...evalDashboardFeatureStateMock,
|
|
32
|
+
workflowContent: workflowMock,
|
|
26
33
|
},
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
export const WithStateManagement: Story = {
|
|
30
37
|
render: () => {
|
|
31
38
|
const state = useEvalDashboardFeatureMock()
|
|
32
|
-
return <EvalDashboardFeature {...state} className="h-[100dvh]" />
|
|
39
|
+
return <EvalDashboardFeature {...state} workflowContent={workflowMock} className="h-[100dvh]" />
|
|
33
40
|
},
|
|
34
41
|
}
|
|
@@ -2,12 +2,12 @@ import * as React from "react"
|
|
|
2
2
|
import { InboxPanel } from "@/components/blocks/InboxPanel"
|
|
3
3
|
import { SectionLayout } from "@/components/blocks/SectionLayout"
|
|
4
4
|
import { DashboardChart } from "@/components/composites/DashboardChart"
|
|
5
|
-
import { EvalSessionDetailsPanel, EvalTriggerButton } from "@/components/
|
|
5
|
+
import { EvalSessionDetailsPanel, EvalTriggerButton } from "@/components/blocks/EvalSessionDetailsPanel"
|
|
6
6
|
import type { DashboardRow } from "@/components/composites/DataTable"
|
|
7
7
|
import { cn } from "@/lib/utils"
|
|
8
|
-
import type {
|
|
9
|
-
EvalDashboardFeatureInboxState,
|
|
10
|
-
EvalDashboardFeatureData,
|
|
8
|
+
import type {
|
|
9
|
+
EvalDashboardFeatureInboxState,
|
|
10
|
+
EvalDashboardFeatureData,
|
|
11
11
|
EvalDashboardFeatureActionHandlers,
|
|
12
12
|
} from "./useEvalDashboardFeature.d"
|
|
13
13
|
|
|
@@ -17,16 +17,17 @@ export interface EvalDashboardFeatureProps {
|
|
|
17
17
|
data: EvalDashboardFeatureData | null
|
|
18
18
|
actionHandlers?: EvalDashboardFeatureActionHandlers
|
|
19
19
|
className?: string
|
|
20
|
+
workflowContent?: React.ReactNode
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
23
|
-
({ inbox, data, actionHandlers, className }) => {
|
|
24
|
+
({ inbox, data, actionHandlers, className, workflowContent }) => {
|
|
24
25
|
const [showInbox, setShowInbox] = React.useState(true)
|
|
25
26
|
const [activeTab, setActiveTab] = React.useState("golden-evals")
|
|
26
27
|
|
|
27
|
-
const selectedSession = React.useMemo(() =>
|
|
28
|
+
const selectedSession = React.useMemo(() =>
|
|
28
29
|
inbox.items.find(s => s.id === inbox.selectedItemId) || null
|
|
29
|
-
|
|
30
|
+
, [inbox.items, inbox.selectedItemId])
|
|
30
31
|
|
|
31
32
|
// Calculate average score for the trend section
|
|
32
33
|
const avgScore = React.useMemo(() => {
|
|
@@ -40,7 +41,6 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
40
41
|
id: session.id,
|
|
41
42
|
title: session.id,
|
|
42
43
|
subtitle: `Score: ${session.score}/${session.total}`,
|
|
43
|
-
preview: `${session.latency} • ${session.tokens}t`,
|
|
44
44
|
timestamp: new Date(session.date).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
45
45
|
}))
|
|
46
46
|
}, [inbox.items]);
|
|
@@ -50,7 +50,7 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
50
50
|
const sortedItems = [...inbox.items].sort(
|
|
51
51
|
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
|
52
52
|
)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
return sortedItems.map(session => ({
|
|
55
55
|
date: session.date,
|
|
56
56
|
// We map score to 'desktop' since DashboardChart is hardcoded for now
|
|
@@ -75,6 +75,7 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
75
75
|
resizable={true}
|
|
76
76
|
padded={false}
|
|
77
77
|
className="h-full"
|
|
78
|
+
storageKey="eval-dashboard-outer"
|
|
78
79
|
sections={[
|
|
79
80
|
...(mockChartData.length > 0 ? [{
|
|
80
81
|
id: "graph",
|
|
@@ -104,8 +105,9 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
104
105
|
}] : []),
|
|
105
106
|
{
|
|
106
107
|
id: "content",
|
|
107
|
-
defaultSize: mockChartData.length > 0 ?
|
|
108
|
+
defaultSize: mockChartData.length > 0 ? 80 : 100,
|
|
108
109
|
minSize: 40,
|
|
110
|
+
variant: "ghost",
|
|
109
111
|
content: (
|
|
110
112
|
<div className="h-full w-full min-h-0">
|
|
111
113
|
<SectionLayout
|
|
@@ -143,7 +145,8 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
143
145
|
tabs: [
|
|
144
146
|
{ label: "Golden Evals", value: "golden-evals" },
|
|
145
147
|
{ label: "System Prompts", value: "prompts" },
|
|
146
|
-
{ label: "Outputs", value: "outputs" }
|
|
148
|
+
{ label: "Outputs", value: "outputs" },
|
|
149
|
+
...(workflowContent ? [{ label: "Workflow", value: "workflow" }] : []),
|
|
147
150
|
],
|
|
148
151
|
defaultTab: activeTab,
|
|
149
152
|
onTabChange: setActiveTab,
|
|
@@ -153,13 +156,15 @@ export const EvalDashboardFeature = React.memo<EvalDashboardFeatureProps>(
|
|
|
153
156
|
onClick: () => setShowInbox(!showInbox)
|
|
154
157
|
},
|
|
155
158
|
actions: actionHandlers?.onTriggerEvaluation ? (
|
|
156
|
-
<EvalTriggerButton onClick={actionHandlers.onTriggerEvaluation} />
|
|
157
|
-
) : undefined
|
|
159
|
+
<EvalTriggerButton onClick={actionHandlers.onTriggerEvaluation} loading={actionHandlers.isTriggering} />
|
|
160
|
+
) : undefined,
|
|
158
161
|
} : undefined,
|
|
159
162
|
content: sessionDetails ? (
|
|
160
|
-
<EvalSessionDetailsPanel
|
|
161
|
-
sessionDetails={sessionDetails}
|
|
162
|
-
activeTab={activeTab}
|
|
163
|
+
<EvalSessionDetailsPanel
|
|
164
|
+
sessionDetails={sessionDetails}
|
|
165
|
+
activeTab={activeTab}
|
|
166
|
+
actionHandlers={actionHandlers}
|
|
167
|
+
workflowContent={workflowContent}
|
|
163
168
|
/>
|
|
164
169
|
) : (
|
|
165
170
|
<div className="flex-1 flex items-center justify-center text-muted-foreground bg-background h-full">
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
mockPageLayoutRefinementMessages,
|
|
10
10
|
mockSidebarConfig,
|
|
11
11
|
} from './PageLayout.mocks'
|
|
12
|
-
import { NodeEditor } from '
|
|
12
|
+
import { NodeEditor } from '@/components/features/NodeEditor'
|
|
13
13
|
import { RefinementPanel } from '../RefinementPanel/RefinementPanel'
|
|
14
|
-
import { mockEdges, mockNodes, mockVersions } from '
|
|
14
|
+
import { mockEdges, mockNodes, mockVersions } from '@/components/features/NodeEditor/NodeEditor.mocks'
|
|
15
15
|
import { DashboardFeature } from '../DashboardFeature/DashboardFeature'
|
|
16
16
|
import { useDashboardIntegrationMock } from './useDashboardIntegration.mock'
|
|
17
17
|
|
|
@@ -17,13 +17,14 @@ export type { RefinementPanelProps, RefinementMessage } from "./RefinementPanel"
|
|
|
17
17
|
export { SpecNavigator } from "./SpecNavigator";
|
|
18
18
|
export type { SpecNavigatorProps } from "./SpecNavigator";
|
|
19
19
|
|
|
20
|
+
// NodeEditor Feature
|
|
21
|
+
export { NodeEditor } from "./NodeEditor";
|
|
22
|
+
export type { NodeEditorProps } from "./NodeEditor";
|
|
23
|
+
|
|
20
24
|
// TextEditor Feature
|
|
21
25
|
export { TextEditor } from "./TextEditor";
|
|
22
26
|
export type { TextEditorProps } from "./TextEditor";
|
|
23
27
|
|
|
24
|
-
// NodeEditor Feature
|
|
25
|
-
export { NodeEditor } from "./NodeEditor";
|
|
26
|
-
export type { NodeEditorProps } from "./NodeEditor";
|
|
27
28
|
|
|
28
29
|
// DashboardFeature Feature
|
|
29
30
|
export { DashboardFeature } from "./DashboardFeature";
|