ai-design-system 0.1.50 → 0.1.52
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/blocks/InboxPanel/InboxPanel.tsx +1 -1
- package/components/blocks/SectionLayout/SectionLayout.tsx +2 -0
- package/components/blocks/SectionLayout/interfaces.ts +1 -0
- package/components/blocks/WorkflowCanvas/WorkflowCanvas.tsx +1 -15
- package/components/composites/AdjustableLayout/AdjustableLayout.tsx +74 -43
- package/components/composites/AppHeader/AppHeader.tsx +16 -2
- package/components/composites/AppHeader/interfaces.ts +1 -0
- package/components/composites/ChatToggleButton/ChatToggleButton.stories.tsx +31 -0
- package/components/composites/ChatToggleButton/ChatToggleButton.tsx +26 -0
- package/components/composites/ChatToggleButton/index.ts +2 -0
- package/components/composites/DashboardChart/DashboardChart.stories.tsx +18 -0
- package/components/composites/DashboardHeader/DashboardHeader.stories.tsx +18 -0
- package/components/composites/FilePreviewDialog/FilePreviewDialog.stories.tsx +18 -0
- package/components/composites/FormReports/FormReports.stories.tsx +18 -0
- package/components/composites/LayoutProvider/LayoutProvider.stories.tsx +18 -0
- package/components/composites/LoadingShimmer/LoadingShimmer.stories.tsx +18 -0
- package/components/composites/ModeSwitcher/ModeSwitcher.stories.tsx +18 -0
- package/components/composites/NavigationList/NavigationList.tsx +8 -1
- package/components/composites/NavigationList/interfaces.ts +1 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +15 -5
- package/components/composites/ProjectSwitcher/ProjectSwitcher.stories.tsx +18 -0
- package/components/composites/PromptInput/PromptInput.tsx +5 -1
- package/components/composites/TriggerNode/TriggerNode.stories.tsx +18 -0
- package/components/composites/UserMessage/UserMessage.tsx +15 -5
- package/components/composites/WorkflowRunObservabilityPanel/WorkflowRunObservabilityPanel.stories.tsx +18 -0
- package/components/composites/index.ts +4 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +75 -63
- package/components/features/PageLayout/PageLayout.tsx +73 -4
- package/components/features/PageLayout/usePageLayout.mock.ts +9 -0
- package/components/features/RefinementPanel/RefinementPanel.tsx +5 -4
- package/components/features/WorkflowObservabilityFeature/WorkflowObservabilityFeature.stories.tsx +18 -22
- package/components/features/WorkflowObservabilityFeature/WorkflowObservabilityFeature.tsx +4 -1
- package/components/index.ts +4 -1
- package/components/primitives/Toaster/Toaster.stories.tsx +366 -0
- package/components/primitives/Toaster/Toaster.tsx +6 -0
- package/components/primitives/Toaster/index.ts +6 -0
- package/components/primitives/index.ts +1 -0
- package/dist/index.cjs +1719 -1613
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +92 -8
- package/dist/index.d.ts +41 -1
- package/dist/index.js +1712 -1615
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,7 @@ export const SectionLayout = React.memo<SectionLayoutProps>(
|
|
|
21
21
|
resizable = true,
|
|
22
22
|
dragHandleColor = "border",
|
|
23
23
|
className,
|
|
24
|
+
padded = true,
|
|
24
25
|
...props
|
|
25
26
|
}) => {
|
|
26
27
|
// Transform sections to include headers
|
|
@@ -47,6 +48,7 @@ export const SectionLayout = React.memo<SectionLayoutProps>(
|
|
|
47
48
|
onSectionResize={onSectionResize}
|
|
48
49
|
dragHandleColor={dragHandleColor}
|
|
49
50
|
className={className}
|
|
51
|
+
padded={padded}
|
|
50
52
|
{...props}
|
|
51
53
|
/>
|
|
52
54
|
)
|
|
@@ -20,4 +20,5 @@ export interface SectionLayoutProps extends React.ComponentPropsWithoutRef<"div"
|
|
|
20
20
|
onSectionResize?: (sectionId: string, newSize: number) => void;
|
|
21
21
|
resizable?: boolean;
|
|
22
22
|
dragHandleColor?: "primary" | "secondary" | "accent" | "border" | "muted";
|
|
23
|
+
padded?: boolean;
|
|
23
24
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type Connection,
|
|
7
7
|
useReactFlow,
|
|
8
8
|
} from "@xyflow/react";
|
|
9
|
-
import { useCallback, useEffect
|
|
9
|
+
import { useCallback, useEffect } from "react";
|
|
10
10
|
import { Canvas } from "@/components/ai-elements/canvas";
|
|
11
11
|
import { Connection as ConnectionLine } from "@/components/ai-elements/connection";
|
|
12
12
|
import { Controls } from "@/components/ai-elements/controls";
|
|
@@ -47,18 +47,6 @@ function WorkflowCanvasInner({
|
|
|
47
47
|
className,
|
|
48
48
|
}: WorkflowCanvasProps) {
|
|
49
49
|
const { fitView } = useReactFlow();
|
|
50
|
-
const viewportInitialized = useRef(false);
|
|
51
|
-
const [isCanvasReady, setIsCanvasReady] = useState(false);
|
|
52
|
-
|
|
53
|
-
useEffect(() => {
|
|
54
|
-
if (!viewportInitialized.current && nodes.length > 0) {
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
fitView({ maxZoom: 1, minZoom: 0.5, padding: 0.2, duration: 0 });
|
|
57
|
-
viewportInitialized.current = true;
|
|
58
|
-
setIsCanvasReady(true);
|
|
59
|
-
}, 0);
|
|
60
|
-
}
|
|
61
|
-
}, [nodes.length, fitView]);
|
|
62
50
|
|
|
63
51
|
useEffect(() => {
|
|
64
52
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
@@ -85,8 +73,6 @@ function WorkflowCanvasInner({
|
|
|
85
73
|
className={className}
|
|
86
74
|
data-testid="workflow-canvas"
|
|
87
75
|
style={{
|
|
88
|
-
opacity: isCanvasReady ? 1 : 0,
|
|
89
|
-
transition: "opacity 300ms",
|
|
90
76
|
width: "100%",
|
|
91
77
|
height: "100%",
|
|
92
78
|
}}
|
|
@@ -18,6 +18,7 @@ export interface AdjustableLayoutProps extends React.ComponentPropsWithoutRef<"d
|
|
|
18
18
|
storageKey?: string // localStorage key for persistence
|
|
19
19
|
onSectionResize?: (sectionId: string, newSize: number) => void
|
|
20
20
|
dragHandleColor?: "primary" | "secondary" | "accent" | "border" | "muted"
|
|
21
|
+
padded?: boolean
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -28,19 +29,20 @@ export interface AdjustableLayoutProps extends React.ComponentPropsWithoutRef<"d
|
|
|
28
29
|
* Supports localStorage persistence and responsive behavior.
|
|
29
30
|
*/
|
|
30
31
|
export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
31
|
-
({
|
|
32
|
-
sections,
|
|
33
|
-
orientation = "horizontal",
|
|
32
|
+
({
|
|
33
|
+
sections,
|
|
34
|
+
orientation = "horizontal",
|
|
34
35
|
storageKey,
|
|
35
36
|
onSectionResize,
|
|
36
37
|
dragHandleColor = "border",
|
|
37
38
|
className,
|
|
38
|
-
|
|
39
|
+
padded = false,
|
|
40
|
+
...props
|
|
39
41
|
}) => {
|
|
40
42
|
// Color mapping for drag handles
|
|
41
43
|
const colorMap = {
|
|
42
44
|
primary: "bg-primary hover:bg-primary/90",
|
|
43
|
-
secondary: "bg-secondary hover:bg-secondary/80",
|
|
45
|
+
secondary: "bg-secondary hover:bg-secondary/80",
|
|
44
46
|
accent: "bg-accent hover:bg-accent/80",
|
|
45
47
|
border: "bg-border hover:bg-border/80",
|
|
46
48
|
muted: "bg-muted hover:bg-muted/80"
|
|
@@ -49,7 +51,7 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
49
51
|
const hoverColorMap = {
|
|
50
52
|
primary: "group-hover:bg-primary/30",
|
|
51
53
|
secondary: "group-hover:bg-secondary/30",
|
|
52
|
-
accent: "group-hover:bg-accent/30",
|
|
54
|
+
accent: "group-hover:bg-accent/30",
|
|
53
55
|
border: "group-hover:bg-border/30",
|
|
54
56
|
muted: "group-hover:bg-muted/30"
|
|
55
57
|
}
|
|
@@ -77,7 +79,7 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
77
79
|
} catch {
|
|
78
80
|
// ignore malformed storage
|
|
79
81
|
}
|
|
80
|
-
|
|
82
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
83
|
}, [storageKey])
|
|
82
84
|
|
|
83
85
|
const [draggingIndex, setDraggingIndex] = React.useState<number | null>(null)
|
|
@@ -119,33 +121,51 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
119
121
|
|
|
120
122
|
const currentX = orientation === "horizontal" ? e.clientX : e.clientY
|
|
121
123
|
const deltaX = currentX - startX
|
|
122
|
-
|
|
124
|
+
|
|
123
125
|
const deltaPercent = (deltaX / containerSize) * 100
|
|
126
|
+
|
|
127
|
+
const p1 = sections[draggingIndex]
|
|
128
|
+
const p2 = sections[draggingIndex + 1]
|
|
129
|
+
|
|
130
|
+
const p1Start = startSizes[draggingIndex]
|
|
131
|
+
const p2Start = startSizes[draggingIndex + 1]
|
|
132
|
+
|
|
133
|
+
const p1Min = p1.minSize ?? 10
|
|
134
|
+
const p1Max = p1.maxSize ?? 80
|
|
135
|
+
const p2Min = p2.minSize ?? 10
|
|
136
|
+
const p2Max = p2.maxSize ?? 80
|
|
137
|
+
|
|
138
|
+
// Calculate how much we can actually change panel 1
|
|
139
|
+
// If deltaPercent > 0, we are growing p1 and shrinking p2
|
|
140
|
+
const maxPositiveDelta = Math.max(0, Math.min(
|
|
141
|
+
p1Max - p1Start, // Space p1 has to grow
|
|
142
|
+
p2Start - p2Min // Space p2 has to shrink
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
// If deltaPercent < 0, we are shrinking p1 and growing p2
|
|
146
|
+
const maxNegativeDelta = Math.min(0, Math.max(
|
|
147
|
+
p1Min - p1Start, // Space p1 has to shrink (negative)
|
|
148
|
+
p2Start - p2Max // Space p2 has to grow (negative)
|
|
149
|
+
))
|
|
150
|
+
|
|
151
|
+
// Clamp the delta
|
|
152
|
+
let clampedDelta = deltaPercent
|
|
153
|
+
if (clampedDelta > 0) {
|
|
154
|
+
clampedDelta = Math.min(clampedDelta, maxPositiveDelta)
|
|
155
|
+
} else {
|
|
156
|
+
clampedDelta = Math.max(clampedDelta, maxNegativeDelta)
|
|
157
|
+
}
|
|
158
|
+
|
|
124
159
|
const newSizes = [...startSizes]
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
Math.min(
|
|
130
|
-
sections[draggingIndex].maxSize ?? 80,
|
|
131
|
-
startSizes[draggingIndex] + deltaPercent
|
|
132
|
-
)
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
newSizes[draggingIndex + 1] = Math.max(
|
|
136
|
-
sections[draggingIndex + 1].minSize ?? 10,
|
|
137
|
-
Math.min(
|
|
138
|
-
sections[draggingIndex + 1].maxSize ?? 80,
|
|
139
|
-
startSizes[draggingIndex + 1] - deltaPercent
|
|
140
|
-
)
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
// Normalize to 100%
|
|
160
|
+
newSizes[draggingIndex] = p1Start + clampedDelta
|
|
161
|
+
newSizes[draggingIndex + 1] = p2Start - clampedDelta
|
|
162
|
+
|
|
163
|
+
// Normalize to 100% just in case of floating point drift
|
|
144
164
|
const total = newSizes.reduce((sum, size) => sum + size, 0)
|
|
145
165
|
const normalizedSizes = newSizes.map(size => (size / total) * 100)
|
|
146
|
-
|
|
166
|
+
|
|
147
167
|
setSizes(normalizedSizes)
|
|
148
|
-
|
|
168
|
+
|
|
149
169
|
// Notify parent
|
|
150
170
|
if (onSectionResize) {
|
|
151
171
|
onSectionResize(sections[draggingIndex].id, normalizedSizes[draggingIndex])
|
|
@@ -183,12 +203,12 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
183
203
|
? { flex: `0 0 ${section.fixedSize}`, width: section.fixedSize, minWidth: section.fixedSize }
|
|
184
204
|
: { flex: `0 0 ${section.fixedSize}`, height: section.fixedSize, minHeight: section.fixedSize }
|
|
185
205
|
: null
|
|
186
|
-
|
|
206
|
+
|
|
187
207
|
return (
|
|
188
208
|
<React.Fragment key={section.id}>
|
|
189
209
|
<div
|
|
190
210
|
className={cn(
|
|
191
|
-
"min-h-0 overflow-hidden bg-card border border-border rounded-
|
|
211
|
+
"min-h-0 overflow-hidden bg-card border border-border rounded-xl",
|
|
192
212
|
section.className
|
|
193
213
|
)}
|
|
194
214
|
style={{
|
|
@@ -199,25 +219,35 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
199
219
|
>
|
|
200
220
|
{section.content}
|
|
201
221
|
</div>
|
|
202
|
-
|
|
222
|
+
|
|
203
223
|
{/* Show drag handle after this panel if it's not the last one */}
|
|
204
224
|
{isResizable && (
|
|
205
225
|
<div
|
|
206
226
|
className={cn(
|
|
207
|
-
|
|
208
|
-
orientation === "vertical"
|
|
209
|
-
? "cursor-row-resize h-
|
|
210
|
-
: "cursor-col-resize w-
|
|
227
|
+
"flex-shrink-0 flex items-center justify-center relative group",
|
|
228
|
+
orientation === "vertical"
|
|
229
|
+
? "cursor-row-resize h-2 w-full"
|
|
230
|
+
: "cursor-col-resize w-2 h-full"
|
|
211
231
|
)}
|
|
212
232
|
onMouseDown={(e) => handleMouseDown(index, e)}
|
|
213
233
|
>
|
|
214
|
-
|
|
234
|
+
{/* Visible pill */}
|
|
235
|
+
<div
|
|
236
|
+
className={cn(
|
|
237
|
+
`${colorMap[dragHandleColor]} transition-colors duration-200 rounded-full`,
|
|
238
|
+
orientation === "vertical"
|
|
239
|
+
? "h-1 w-8"
|
|
240
|
+
: "w-1 h-8"
|
|
241
|
+
)}
|
|
242
|
+
/>
|
|
243
|
+
{/* Invisible large hit area */}
|
|
244
|
+
<div
|
|
215
245
|
className={cn(
|
|
216
|
-
|
|
217
|
-
orientation === "vertical"
|
|
218
|
-
? "
|
|
219
|
-
: "
|
|
220
|
-
)}
|
|
246
|
+
"absolute z-10",
|
|
247
|
+
orientation === "vertical"
|
|
248
|
+
? "inset-x-0 -top-2 -bottom-2"
|
|
249
|
+
: "inset-y-0 -left-2 -right-2"
|
|
250
|
+
)}
|
|
221
251
|
/>
|
|
222
252
|
</div>
|
|
223
253
|
)}
|
|
@@ -230,12 +260,13 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
|
|
|
230
260
|
ref={containerRef}
|
|
231
261
|
className={cn(
|
|
232
262
|
"flex overflow-hidden h-full gap-1 min-w-0",
|
|
263
|
+
padded && "p-4",
|
|
233
264
|
orientation === "horizontal" ? "flex-row" : "flex-col",
|
|
234
265
|
className
|
|
235
266
|
)}
|
|
236
267
|
{...props}
|
|
237
268
|
>
|
|
238
|
-
{sections.map((section, index) =>
|
|
269
|
+
{sections.map((section, index) =>
|
|
239
270
|
renderPanel(section, sizes[index], index)
|
|
240
271
|
)}
|
|
241
272
|
</div>
|
|
@@ -11,6 +11,7 @@ export const AppHeader = React.memo<AppHeaderProps>(({
|
|
|
11
11
|
defaultTab,
|
|
12
12
|
onTabChange,
|
|
13
13
|
className,
|
|
14
|
+
tabsPosition = 'center',
|
|
14
15
|
showSidebarToggle = true,
|
|
15
16
|
showTitle = true
|
|
16
17
|
}) => {
|
|
@@ -30,7 +31,7 @@ export const AppHeader = React.memo<AppHeaderProps>(({
|
|
|
30
31
|
</div>
|
|
31
32
|
|
|
32
33
|
<div className="justify-self-center">
|
|
33
|
-
{tabs && tabs.length > 0 && (
|
|
34
|
+
{tabsPosition === 'center' && tabs && tabs.length > 0 && (
|
|
34
35
|
<Tabs defaultValue={defaultTab || tabs[0]?.value} onValueChange={onTabChange}>
|
|
35
36
|
<TabsList>
|
|
36
37
|
{tabs.map((tab) => (
|
|
@@ -43,7 +44,20 @@ export const AppHeader = React.memo<AppHeaderProps>(({
|
|
|
43
44
|
)}
|
|
44
45
|
</div>
|
|
45
46
|
|
|
46
|
-
<div className="flex min-w-0 items-center justify-end gap-2">
|
|
47
|
+
<div className="flex min-w-0 items-center justify-end gap-2">
|
|
48
|
+
{tabsPosition === 'right' && tabs && tabs.length > 0 && (
|
|
49
|
+
<Tabs defaultValue={defaultTab || tabs[0]?.value} onValueChange={onTabChange}>
|
|
50
|
+
<TabsList>
|
|
51
|
+
{tabs.map((tab) => (
|
|
52
|
+
<TabsTrigger key={tab.value} value={tab.value}>
|
|
53
|
+
{tab.label}
|
|
54
|
+
</TabsTrigger>
|
|
55
|
+
))}
|
|
56
|
+
</TabsList>
|
|
57
|
+
</Tabs>
|
|
58
|
+
)}
|
|
59
|
+
{actions}
|
|
60
|
+
</div>
|
|
47
61
|
</div>
|
|
48
62
|
</header>
|
|
49
63
|
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { ChatToggleButton } from './ChatToggleButton'
|
|
3
|
+
import { fn } from '@storybook/test'
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'Composites/ChatToggleButton',
|
|
7
|
+
component: ChatToggleButton,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
},
|
|
12
|
+
} satisfies Meta<typeof ChatToggleButton>
|
|
13
|
+
|
|
14
|
+
export default meta
|
|
15
|
+
type Story = StoryObj<typeof meta>
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
isOpen: true,
|
|
20
|
+
label: "Hide Chat",
|
|
21
|
+
onClick: fn(),
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Closed: Story = {
|
|
26
|
+
args: {
|
|
27
|
+
isOpen: false,
|
|
28
|
+
label: "Show Chat",
|
|
29
|
+
onClick: fn(),
|
|
30
|
+
},
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Button, type ButtonProps } from "@/components/primitives/Button"
|
|
2
|
+
import { Icon } from "@/components/primitives/Icon"
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
|
|
5
|
+
export interface ChatToggleButtonProps extends Omit<ButtonProps, "children"> {
|
|
6
|
+
isOpen?: boolean
|
|
7
|
+
label?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function ChatToggleButton({
|
|
11
|
+
isOpen = true,
|
|
12
|
+
label = "Hide Chat",
|
|
13
|
+
className,
|
|
14
|
+
...props
|
|
15
|
+
}: ChatToggleButtonProps) {
|
|
16
|
+
return (
|
|
17
|
+
<Button
|
|
18
|
+
variant="ghost"
|
|
19
|
+
className={`-ml-2 h-8 text-muted-foreground hover:text-foreground ${className ?? ""}`}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
<Icon name="panel-left" size="sm" />
|
|
23
|
+
{label}
|
|
24
|
+
</Button>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { DashboardChart } from './DashboardChart'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/DashboardChart',
|
|
6
|
+
component: DashboardChart,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof DashboardChart>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { DashboardHeader } from './DashboardHeader'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/DashboardHeader',
|
|
6
|
+
component: DashboardHeader,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof DashboardHeader>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { FilePreviewDialog } from './FilePreviewDialog'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/FilePreviewDialog',
|
|
6
|
+
component: FilePreviewDialog,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof FilePreviewDialog>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { FormReports } from './FormReports'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/FormReports',
|
|
6
|
+
component: FormReports,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof FormReports>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { LayoutProvider } from './LayoutProvider'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/LayoutProvider',
|
|
6
|
+
component: LayoutProvider,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof LayoutProvider>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { LoadingShimmer } from './LoadingShimmer'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/LoadingShimmer',
|
|
6
|
+
component: LoadingShimmer,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof LoadingShimmer>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { ModeSwitcher } from './ModeSwitcher'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/ModeSwitcher',
|
|
6
|
+
component: ModeSwitcher,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof ModeSwitcher>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -12,6 +12,7 @@ export interface NavigationItem {
|
|
|
12
12
|
url: string
|
|
13
13
|
icon?: string
|
|
14
14
|
isActive?: boolean
|
|
15
|
+
onClick?: (e: React.MouseEvent) => void
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export interface NavigationListProps {
|
|
@@ -29,7 +30,13 @@ export const NavigationList = React.memo<NavigationListProps>(
|
|
|
29
30
|
<SidebarMenuButton
|
|
30
31
|
tooltip={item.title}
|
|
31
32
|
isActive={item.isActive}
|
|
32
|
-
onClick={() =>
|
|
33
|
+
onClick={(e) => {
|
|
34
|
+
if (item.onClick) {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
item.onClick(e);
|
|
37
|
+
}
|
|
38
|
+
onItemClick?.(item)
|
|
39
|
+
}}
|
|
33
40
|
asChild
|
|
34
41
|
>
|
|
35
42
|
<a href={item.url}>
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
Avatar,
|
|
4
|
+
AvatarFallback,
|
|
5
|
+
} from "@/components/primitives/Avatar"
|
|
6
|
+
import { Icon } from "@/components/primitives/Icon"
|
|
2
7
|
import {
|
|
3
8
|
Message,
|
|
4
9
|
MessageContent,
|
|
@@ -49,11 +54,16 @@ export const OrchestratorMessage = React.memo<OrchestratorMessageProps>(
|
|
|
49
54
|
|
|
50
55
|
return (
|
|
51
56
|
<Message from="assistant">
|
|
52
|
-
{showAvatar && (
|
|
53
|
-
<MessageAvatar
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
{showAvatar && (message.avatarSrc
|
|
58
|
+
? <MessageAvatar
|
|
59
|
+
src={message.avatarSrc}
|
|
60
|
+
name={message.avatarName || "Coordinator"}
|
|
61
|
+
/>
|
|
62
|
+
: <Avatar className="size-8 ring-1 ring-border">
|
|
63
|
+
<AvatarFallback>
|
|
64
|
+
<Icon name="bot" />
|
|
65
|
+
</AvatarFallback>
|
|
66
|
+
</Avatar>
|
|
57
67
|
)}
|
|
58
68
|
|
|
59
69
|
<div className="flex-1 min-w-0">
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { ProjectSwitcher } from './ProjectSwitcher'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/ProjectSwitcher',
|
|
6
|
+
component: ProjectSwitcher,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof ProjectSwitcher>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
type PromptInputProps as AIPromptInputProps,
|
|
15
15
|
} from "@/components/ai-elements/prompt-input";
|
|
16
16
|
import type { FormEvent } from "react";
|
|
17
|
+
import { Button } from "@/components/primitives/Button";
|
|
18
|
+
import { Icon } from "@/components/primitives/Icon";
|
|
17
19
|
|
|
18
20
|
export interface PromptInputBlockProps
|
|
19
21
|
extends Omit<
|
|
@@ -80,7 +82,9 @@ export const PromptInput = React.memo<PromptInputBlockProps>(
|
|
|
80
82
|
</PromptInputBody>
|
|
81
83
|
<PromptInputFooter>
|
|
82
84
|
<PromptInputTools>
|
|
83
|
-
{}
|
|
85
|
+
<Button variant="ghost" size="icon" className="h-8 w-8 rounded-full" type="button" disabled={disabled}>
|
|
86
|
+
<Icon name="plus" size="sm" />
|
|
87
|
+
</Button>
|
|
84
88
|
</PromptInputTools>
|
|
85
89
|
<PromptInputSubmit disabled={disabled} status={loading ? "submitted" : undefined} />
|
|
86
90
|
</PromptInputFooter>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { TriggerNode } from './TriggerNode'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Composites/TriggerNode',
|
|
6
|
+
component: TriggerNode,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof TriggerNode>
|
|
12
|
+
|
|
13
|
+
export default meta
|
|
14
|
+
type Story = StoryObj<typeof meta>
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {} as any,
|
|
18
|
+
}
|