ai-design-system 0.1.26 → 0.1.28

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.
@@ -16,12 +16,17 @@ export const AppHeader = React.memo<AppHeaderProps>(({
16
16
  }) => {
17
17
  return (
18
18
  <header className={`flex h-14 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-14 ${className || ""}`}>
19
- <div className="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
20
- {showSidebarToggle && <SidebarTrigger className="-ml-1" />}
21
- {showSidebarToggle && title && <Separator orientation="vertical" className="mx-2 data-[orientation=vertical]:h-4" />}
22
- {showTitle && title && <h1 className="text-base font-medium">{title}</h1>}
23
- {tabs && tabs.length > 0 && (
24
- <div className="flex-1 flex justify-center">
19
+ <div className="grid w-full grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center px-4 lg:px-6">
20
+ <div className="min-w-0 flex items-center gap-1 lg:gap-2">
21
+ {showSidebarToggle && <SidebarTrigger className="-ml-1" />}
22
+ {showSidebarToggle && showTitle && title && (
23
+ <Separator orientation="vertical" className="mx-2 data-[orientation=vertical]:h-4" />
24
+ )}
25
+ {showTitle && title && <h1 className="max-w-[28rem] truncate text-base font-medium">{title}</h1>}
26
+ </div>
27
+
28
+ <div className="justify-self-center">
29
+ {tabs && tabs.length > 0 && (
25
30
  <Tabs defaultValue={defaultTab || tabs[0]?.value} onValueChange={onTabChange}>
26
31
  <TabsList>
27
32
  {tabs.map((tab) => (
@@ -31,9 +36,10 @@ export const AppHeader = React.memo<AppHeaderProps>(({
31
36
  ))}
32
37
  </TabsList>
33
38
  </Tabs>
34
- </div>
35
- )}
36
- <div className="ml-auto flex items-center gap-2">{actions}</div>
39
+ )}
40
+ </div>
41
+
42
+ <div className="flex min-w-0 items-center justify-end gap-2">{actions}</div>
37
43
  </div>
38
44
  </header>
39
45
  )
@@ -1,5 +1,4 @@
1
1
  import type { Meta, StoryObj } from "@storybook/nextjs-vite"
2
- import { useState } from "react"
3
2
 
4
3
  import { WorkflowObservabilityFeature } from "./WorkflowObservabilityFeature"
5
4
  import {
@@ -61,8 +60,6 @@ export const WithStateManagement: Story = {
61
60
  args: baseArgs,
62
61
  render: () => {
63
62
  const state = useWorkflowObservabilityFeatureMock()
64
- const [searchQuery, setSearchQuery] = useState("")
65
- const [selectedItemId, setSelectedItemId] = useState<string | null>(state.selectedRun.runId)
66
63
 
67
64
  return (
68
65
  <div className="h-dvh min-h-0 p-2">
@@ -76,13 +73,11 @@ export const WithStateManagement: Story = {
76
73
  runActions={state.runActions}
77
74
  onSearchQueryChange={state.actionHandlers?.onSearchQueryChange}
78
75
  onSelectSpan={state.actionHandlers?.onSelectSpan}
79
- inbox={{
80
- items: workflowInboxItemsMock,
81
- selectedItemId,
82
- onSelectItem: setSelectedItemId,
83
- searchQuery,
84
- onSearchQueryChange: setSearchQuery,
85
- }}
76
+ inbox={state.inbox ? {
77
+ ...state.inbox,
78
+ onSelectItem: state.actionHandlers?.onSelectInboxItem,
79
+ onSearchQueryChange: state.actionHandlers?.onInboxSearchQueryChange,
80
+ } : undefined}
86
81
  className="h-full"
87
82
  />
88
83
  </div>
@@ -5,10 +5,21 @@ import type {
5
5
  WorkflowSpanRecord,
6
6
  WorkflowStreamRecord,
7
7
  } from "@/components/composites/WorkflowRunObservabilityPanel"
8
+ import type { InboxListItem } from "@/components/composites/InboxList"
8
9
 
9
10
  export interface WorkflowObservabilityFeatureActionHandlers {
10
11
  onSearchQueryChange?: (value: string) => void
11
12
  onSelectSpan?: (spanId: string | null) => void
13
+ onInboxSearchQueryChange?: (value: string) => void
14
+ onSelectInboxItem?: (itemId: string) => void
15
+ }
16
+
17
+ export interface WorkflowObservabilityFeatureInboxState {
18
+ items: InboxListItem[]
19
+ selectedItemId?: string | null
20
+ searchQuery?: string
21
+ isLoading?: boolean
22
+ emptyMessage?: string
12
23
  }
13
24
 
14
25
  export interface UseWorkflowObservabilityFeatureReturn {
@@ -19,6 +30,7 @@ export interface UseWorkflowObservabilityFeatureReturn {
19
30
  searchQuery?: string
20
31
  selectedSpanId?: string | null
21
32
  runActions?: WorkflowRunAction[]
33
+ inbox?: WorkflowObservabilityFeatureInboxState
22
34
  actionHandlers?: WorkflowObservabilityFeatureActionHandlers
23
35
  }
24
36
 
@@ -4,18 +4,46 @@ import type { UseWorkflowObservabilityFeatureReturn } from "./useWorkflowObserva
4
4
  import {
5
5
  selectedWorkflowRunMock,
6
6
  workflowEventRecordsMock,
7
+ workflowInboxItemsMock,
7
8
  workflowSpanRecordsMock,
8
9
  workflowStreamRecordsMock,
9
10
  } from "./WorkflowObservabilityFeature.mocks"
10
11
 
12
+ const runByInboxId: Record<string, typeof selectedWorkflowRunMock> = {
13
+ [selectedWorkflowRunMock.runId]: selectedWorkflowRunMock,
14
+ wrun_01KP45XGBHRMT7HQJXXHKBEQS5: {
15
+ ...selectedWorkflowRunMock,
16
+ runId: "wrun_01KP45XGBHRMT7HQJXXHKBEQS5",
17
+ status: "completed",
18
+ createdAt: "7m ago",
19
+ completedAt: "today 12:45 PM",
20
+ duration: "43s",
21
+ suspensionReason: "-",
22
+ },
23
+ }
24
+
11
25
  export function useWorkflowObservabilityFeatureMock(): UseWorkflowObservabilityFeatureReturn {
12
26
  const [searchQuery, setSearchQuery] = React.useState("")
13
27
  const [selectedSpanId, setSelectedSpanId] = React.useState<string | null>(null)
28
+ const [inboxSearchQuery, setInboxSearchQuery] = React.useState("")
29
+ const [selectedInboxItemId, setSelectedInboxItemId] = React.useState<string | null>(selectedWorkflowRunMock.runId)
14
30
  const [selectedRun, setSelectedRun] = React.useState(selectedWorkflowRunMock)
15
31
  const [spans, setSpans] = React.useState(workflowSpanRecordsMock)
16
32
  const [events, setEvents] = React.useState(workflowEventRecordsMock)
17
33
  const [streams, setStreams] = React.useState(workflowStreamRecordsMock)
18
34
 
35
+ const inboxItems = React.useMemo(() => {
36
+ const normalizedQuery = inboxSearchQuery.trim().toLowerCase()
37
+ if (!normalizedQuery) {
38
+ return workflowInboxItemsMock
39
+ }
40
+
41
+ return workflowInboxItemsMock.filter((item) => {
42
+ const searchText = [item.title, item.subtitle, item.preview].filter(Boolean).join(" ").toLowerCase()
43
+ return searchText.includes(normalizedQuery)
44
+ })
45
+ }, [inboxSearchQuery])
46
+
19
47
  const isRunActive = selectedRun.status === "pending" || selectedRun.status === "running"
20
48
  const hasPendingSleeps = React.useMemo(
21
49
  () => spans.some((span) => span.resource === "sleep" && span.state === "live"),
@@ -70,6 +98,7 @@ export function useWorkflowObservabilityFeatureMock(): UseWorkflowObservabilityF
70
98
  suspensionReason: "webhook",
71
99
  }))
72
100
 
101
+ setSelectedInboxItemId(newRunId)
73
102
  setSelectedSpanId("span_generateBirthdayCard")
74
103
 
75
104
  appendEventAndStream("run_replayed", "A new run was started from replay action.", {
@@ -177,6 +206,16 @@ export function useWorkflowObservabilityFeatureMock(): UseWorkflowObservabilityF
177
206
  })
178
207
  }, [appendEventAndStream, selectedRun.runId])
179
208
 
209
+ const selectInboxItem = React.useCallback((itemId: string) => {
210
+ setSelectedInboxItemId(itemId)
211
+ setSelectedSpanId(null)
212
+
213
+ const nextRun = runByInboxId[itemId]
214
+ if (nextRun) {
215
+ setSelectedRun(nextRun)
216
+ }
217
+ }, [])
218
+
180
219
  return {
181
220
  selectedRun,
182
221
  spans,
@@ -184,6 +223,13 @@ export function useWorkflowObservabilityFeatureMock(): UseWorkflowObservabilityF
184
223
  streams,
185
224
  searchQuery,
186
225
  selectedSpanId,
226
+ inbox: {
227
+ items: inboxItems,
228
+ selectedItemId: selectedInboxItemId,
229
+ searchQuery: inboxSearchQuery,
230
+ isLoading: false,
231
+ emptyMessage: "No runs found.",
232
+ },
187
233
  runActions: [
188
234
  {
189
235
  id: "replay-run",
@@ -233,6 +279,8 @@ export function useWorkflowObservabilityFeatureMock(): UseWorkflowObservabilityF
233
279
  actionHandlers: {
234
280
  onSearchQueryChange: setSearchQuery,
235
281
  onSelectSpan: setSelectedSpanId,
282
+ onInboxSearchQueryChange: setInboxSearchQuery,
283
+ onSelectInboxItem: selectInboxItem,
236
284
  },
237
285
  }
238
286
  }
package/dist/index.cjs CHANGED
@@ -6897,12 +6897,14 @@ var AppHeader = React33__namespace.memo(({
6897
6897
  showTitle = true
6898
6898
  }) => {
6899
6899
  var _a;
6900
- return /* @__PURE__ */ jsxRuntime.jsx("header", { className: `flex h-14 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-14 ${className || ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6", children: [
6901
- showSidebarToggle && /* @__PURE__ */ jsxRuntime.jsx(SidebarTrigger2, { className: "-ml-1" }),
6902
- showSidebarToggle && title && /* @__PURE__ */ jsxRuntime.jsx(Separator4, { orientation: "vertical", className: "mx-2 data-[orientation=vertical]:h-4" }),
6903
- showTitle && title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-base font-medium", children: title }),
6904
- tabs && tabs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Tabs2, { defaultValue: defaultTab || ((_a = tabs[0]) == null ? void 0 : _a.value), onValueChange: onTabChange, children: /* @__PURE__ */ jsxRuntime.jsx(TabsList, { children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)) }) }) }),
6905
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center gap-2", children: actions })
6900
+ return /* @__PURE__ */ jsxRuntime.jsx("header", { className: `flex h-14 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-14 ${className || ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center px-4 lg:px-6", children: [
6901
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex items-center gap-1 lg:gap-2", children: [
6902
+ showSidebarToggle && /* @__PURE__ */ jsxRuntime.jsx(SidebarTrigger2, { className: "-ml-1" }),
6903
+ showSidebarToggle && showTitle && title && /* @__PURE__ */ jsxRuntime.jsx(Separator4, { orientation: "vertical", className: "mx-2 data-[orientation=vertical]:h-4" }),
6904
+ showTitle && title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "max-w-[28rem] truncate text-base font-medium", children: title })
6905
+ ] }),
6906
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "justify-self-center", children: tabs && tabs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Tabs2, { defaultValue: defaultTab || ((_a = tabs[0]) == null ? void 0 : _a.value), onValueChange: onTabChange, children: /* @__PURE__ */ jsxRuntime.jsx(TabsList, { children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)) }) }) }),
6907
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center justify-end gap-2", children: actions })
6906
6908
  ] }) });
6907
6909
  });
6908
6910
  AppHeader.displayName = "AppHeader";
@@ -10710,6 +10712,34 @@ var WorkflowObservabilityFeature = React33__namespace.memo(
10710
10712
  WorkflowObservabilityFeature.displayName = "WorkflowObservabilityFeature";
10711
10713
 
10712
10714
  // components/features/WorkflowObservabilityFeature/WorkflowObservabilityFeature.mocks.ts
10715
+ var selectedWorkflowRunMock = {
10716
+ runId: "wrun_01KP45XGBHRMT7HQJXXHKBEQS4",
10717
+ workflowName: "generateBirthdayCard",
10718
+ status: "running",
10719
+ createdAt: "1m ago",
10720
+ startedAt: "today 12:44 PM",
10721
+ completedAt: "-",
10722
+ duration: "1m 43s",
10723
+ expiresAt: "-",
10724
+ storage: "5 MB",
10725
+ moduleSpecifier: "./app/api/generate/generate-birthday-card.ts",
10726
+ resumeAt: "4/23/2026, 12:00:00 AM",
10727
+ suspensionReason: "webhook",
10728
+ argumentsPayload: {
10729
+ recipientName: "Maya",
10730
+ tone: "friendly",
10731
+ includeEmoji: true
10732
+ },
10733
+ inputPayload: {
10734
+ prompt: "Generate a birthday greeting card with confetti accents",
10735
+ locale: "en-US"
10736
+ },
10737
+ outputPayload: {
10738
+ cardId: "card_90210",
10739
+ status: "draft",
10740
+ revision: 3
10741
+ }
10742
+ };
10713
10743
  [
10714
10744
  {
10715
10745
  id: "stream_1",
@@ -10725,6 +10755,19 @@ WorkflowObservabilityFeature.displayName = "WorkflowObservabilityFeature";
10725
10755
  }
10726
10756
  ];
10727
10757
 
10758
+ // components/features/WorkflowObservabilityFeature/useWorkflowObservabilityFeature.mock.ts
10759
+ ({
10760
+ [selectedWorkflowRunMock.runId]: selectedWorkflowRunMock,
10761
+ wrun_01KP45XGBHRMT7HQJXXHKBEQS5: __spreadProps(__spreadValues({}, selectedWorkflowRunMock), {
10762
+ runId: "wrun_01KP45XGBHRMT7HQJXXHKBEQS5",
10763
+ status: "completed",
10764
+ createdAt: "7m ago",
10765
+ completedAt: "today 12:45 PM",
10766
+ duration: "43s",
10767
+ suspensionReason: "-"
10768
+ })
10769
+ });
10770
+
10728
10771
  exports.AIConversation = AIConversation;
10729
10772
  exports.AIDocEditor = AIDocEditor;
10730
10773
  exports.Accordion = Accordion2;