ai-design-system 0.1.41 → 0.1.43

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.
Files changed (30) hide show
  1. package/components/blocks/AIConversation/AIConversation.tsx +12 -4
  2. package/components/blocks/WorkflowCanvas/WorkflowCanvas.tsx +2 -1
  3. package/components/composites/AppHeader/AppHeader.mocks.ts +1 -1
  4. package/components/composites/DataTable/DataTable.tsx +3 -2
  5. package/components/composites/DataTable/EnhancedDataTable.tsx +1 -1
  6. package/components/composites/DataTable/InlineEditCell.tsx +7 -5
  7. package/components/composites/DataTable/ReviewerCell.tsx +2 -2
  8. package/components/composites/DataTable/RowDetailDrawer.tsx +8 -8
  9. package/components/composites/DataTable/StatusCell.tsx +1 -1
  10. package/components/composites/DataTable/useEnhancedDataTable.ts +3 -3
  11. package/components/composites/DocumentTabBar/DocumentTabBar.tsx +8 -2
  12. package/components/composites/FilePreviewDialog/FilePreviewDialog.tsx +15 -10
  13. package/components/composites/FormReports/FormReportsDrawerForm.tsx +14 -7
  14. package/components/features/AIDocEditor/AIDocEditor.mocks.ts +14 -1
  15. package/components/features/AIDocEditor/AIDocEditor.tsx +7 -2
  16. package/components/features/AIDocEditor/useAIDocEditor.mock.ts +18 -4
  17. package/components/features/DashboardFeature/DashboardFeature.mocks.ts +7 -7
  18. package/components/features/FormReportsFeature/FormReportsFeature.mocks.ts +11 -50
  19. package/components/features/RefinementPanel/useRefinementPanel.mock.ts +1 -1
  20. package/components/features/SpecNavigator/SpecNavigator.tsx +33 -10
  21. package/components/features/WorkflowBuilder/useWorkflowBuilder.mock.ts +4 -0
  22. package/components/index.ts +1 -1
  23. package/components/primitives/Drawer/Drawer.tsx +7 -11
  24. package/components/primitives/Popover/Popover.tsx +2 -5
  25. package/dist/index.cjs +42 -121
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +38 -18
  28. package/dist/index.js +43 -122
  29. package/dist/index.js.map +1 -1
  30. package/package.json +5 -3
@@ -6,12 +6,11 @@ import {
6
6
  ConversationScrollButton,
7
7
  type ConversationProps,
8
8
  } from "@/components/ai-elements/conversation"
9
- import { type AIMessage } from "@/components/composites/AgentMessage"
9
+ import type { ToolCall, SubAgent } from "@/components/composites"
10
10
  import { UserMessage } from "@/components/composites/UserMessage"
11
11
  import { SpecialistMessage } from "@/components/composites/SpecialistMessage"
12
12
  import { OrchestratorMessage } from "@/components/composites/OrchestratorMessage"
13
13
  import { ToolCallDisplay } from "@/components/composites/ToolCallDisplay"
14
- import type { SubAgent } from "@/components/composites/AgentIndicator"
15
14
 
16
15
  /**
17
16
  * AIConversation Section
@@ -23,6 +22,17 @@ import type { SubAgent } from "@/components/composites/AgentIndicator"
23
22
  * Based on reference implementation from deep-agents-ui ChatInterface.
24
23
  */
25
24
 
25
+ interface AIMessage {
26
+ id: string;
27
+ type: 'human' | 'ai';
28
+ role: string;
29
+ content: string;
30
+ avatarSrc?: string;
31
+ avatarName?: string;
32
+ toolCalls?: ToolCall[];
33
+ subAgents?: SubAgent[];
34
+ }
35
+
26
36
  export interface AIConversationProps
27
37
  extends Omit<ConversationProps, "children"> {
28
38
  /**
@@ -137,7 +147,6 @@ export const AIConversation = React.memo<AIConversationProps>(
137
147
  status: subAgent.status,
138
148
  toolCalls: [],
139
149
  }}
140
- showAvatar={showAvatars}
141
150
  isNested={true}
142
151
  />
143
152
  ))}
@@ -156,7 +165,6 @@ export const AIConversation = React.memo<AIConversationProps>(
156
165
  toolCalls: message.toolCalls?.filter((tc) => tc.name !== "task"),
157
166
  status: "completed",
158
167
  }}
159
- showAvatar={showAvatars}
160
168
  isNested={false}
161
169
  />
162
170
  )
@@ -109,7 +109,8 @@ function WorkflowCanvasInner({
109
109
  onEdgesChange={onEdgesChange}
110
110
  onNodesChange={onNodesChange}
111
111
  onPaneClick={onPaneClick}
112
- onNodeClick={onNodeClick}
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ onNodeClick={onNodeClick as any}
113
114
  onEdgeClick={onEdgeClick}
114
115
  >
115
116
  {topLeft && (
@@ -5,7 +5,7 @@
5
5
  * - AppHeader.stories.tsx
6
6
  */
7
7
 
8
- import type { TabItem } from './AppHeader'
8
+ import type { TabItem } from './interfaces'
9
9
 
10
10
  export const mockTabs: TabItem[] = [
11
11
  { value: 'agent', label: 'Agent' },
@@ -8,6 +8,7 @@ import {
8
8
  flexRender,
9
9
  type ColumnDef,
10
10
  } from "@tanstack/react-table"
11
+ import type { Table as TanStackTable } from "@tanstack/react-table"
11
12
  import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/primitives/Table"
12
13
  import { TablePagination } from "@/components/composites/TablePagination"
13
14
  import { TableToolbar } from "@/components/composites/TableToolbar"
@@ -45,7 +46,7 @@ export function DataTable<TData, TValue>({
45
46
 
46
47
  return (
47
48
  <div className={`space-y-4 ${className || ""}`}>
48
- {enableFiltering && <TableToolbar table={table} searchColumn={searchColumn} />}
49
+ {enableFiltering && <TableToolbar table={table as unknown as TanStackTable<unknown>} searchColumn={searchColumn} />}
49
50
  <div className="rounded-md border">
50
51
  <Table>
51
52
  <TableHeader>
@@ -87,7 +88,7 @@ export function DataTable<TData, TValue>({
87
88
  </TableBody>
88
89
  </Table>
89
90
  </div>
90
- {enablePagination && <TablePagination table={table} />}
91
+ {enablePagination && <TablePagination table={table as unknown as TanStackTable<unknown>} />}
91
92
  </div>
92
93
  )
93
94
  }
@@ -439,7 +439,7 @@ export function EnhancedDataTable({
439
439
  (event: DragEndEvent) => {
440
440
  const { active, over } = event
441
441
  if (active && over && active.id !== over.id) {
442
- reorderById(active.id, over.id)
442
+ reorderById(String(active.id), String(over.id))
443
443
  }
444
444
  },
445
445
  [reorderById]
@@ -14,16 +14,18 @@ export interface InlineEditCellProps {
14
14
  export function InlineEditCell({ row, field, onSave }: InlineEditCellProps) {
15
15
  const inputId = `${row.id}-${field}`
16
16
  const defaultValue = row[field]
17
+ const rowId = row.id as number
18
+ const rowHeader = row.header as string
17
19
 
18
20
  const onSubmit = React.useCallback(
19
21
  (event: React.FormEvent<HTMLFormElement>) => {
20
22
  event.preventDefault()
21
23
  const formData = new FormData(event.currentTarget)
22
24
  const value = String(formData.get(field) ?? "").trim()
23
- onSave(row.id, field, value)
24
- toast.success(`Saved ${field} for ${row.header}`)
25
+ onSave(rowId, field, value)
26
+ toast.success(`Saved ${field} for ${rowHeader}`)
25
27
  },
26
- [field, onSave, row.header, row.id]
28
+ [field, onSave, rowId, rowHeader]
27
29
  )
28
30
 
29
31
  return (
@@ -34,10 +36,10 @@ export function InlineEditCell({ row, field, onSave }: InlineEditCellProps) {
34
36
  <Input
35
37
  id={inputId}
36
38
  name={field}
37
- defaultValue={defaultValue}
39
+ defaultValue={String(defaultValue)}
38
40
  className="h-8 w-16 border-transparent bg-transparent text-right shadow-none hover:bg-input/30 focus-visible:border focus-visible:bg-background"
39
41
  onBlur={(event) => {
40
- onSave(row.id, field, event.target.value)
42
+ onSave(row.id as number, field, event.target.value)
41
43
  }}
42
44
  />
43
45
  </form>
@@ -16,7 +16,7 @@ export function ReviewerCell({ row, onAssign }: ReviewerCellProps) {
16
16
  const isAssigned = row.reviewer !== "Assign reviewer"
17
17
 
18
18
  if (isAssigned) {
19
- return <span>{row.reviewer}</span>
19
+ return <span>{row.reviewer as React.ReactNode}</span>
20
20
  }
21
21
 
22
22
  const id = `${row.id}-reviewer`
@@ -26,7 +26,7 @@ export function ReviewerCell({ row, onAssign }: ReviewerCellProps) {
26
26
  <Label htmlFor={id} className="sr-only">
27
27
  Reviewer
28
28
  </Label>
29
- <Select onValueChange={(value) => onAssign(row.id, value)}>
29
+ <Select onValueChange={(value) => onAssign(row.id as number, value)}>
30
30
  <SelectTrigger id={id} className="w-[170px]">
31
31
  <SelectValue placeholder="Assign reviewer" />
32
32
  </SelectTrigger>
@@ -67,12 +67,12 @@ export function RowDetailDrawer({ item, onChange }: RowDetailDrawerProps) {
67
67
  <Drawer open={open} onOpenChange={setOpen} direction={isMobile ? "bottom" : "right"}>
68
68
  <DrawerTrigger asChild>
69
69
  <Button variant="link" className="w-fit px-0 text-left text-foreground">
70
- {item.header}
70
+ {item.header as React.ReactNode}
71
71
  </Button>
72
72
  </DrawerTrigger>
73
73
  <DrawerContent>
74
74
  <DrawerHeader className="gap-1">
75
- <DrawerTitle>{item.header}</DrawerTitle>
75
+ <DrawerTitle>{item.header as React.ReactNode}</DrawerTitle>
76
76
  <DrawerDescription>Showing total visitors for the last 6 months</DrawerDescription>
77
77
  </DrawerHeader>
78
78
  <div className="flex flex-col gap-4 overflow-y-auto px-4 text-sm">
@@ -103,12 +103,12 @@ export function RowDetailDrawer({ item, onChange }: RowDetailDrawerProps) {
103
103
  <form className="flex flex-col gap-4" onSubmit={(e) => e.preventDefault()}>
104
104
  <div className="flex flex-col gap-3">
105
105
  <Label htmlFor="drawer-header">Header</Label>
106
- <Input id="drawer-header" defaultValue={item.header} onBlur={(e) => onChange(item.id, "header", e.target.value)} />
106
+ <Input id="drawer-header" defaultValue={String(item.header)} onBlur={(e) => onChange(item.id as number, "header", e.target.value)} />
107
107
  </div>
108
108
  <div className="grid grid-cols-2 gap-4">
109
109
  <div className="flex flex-col gap-3">
110
110
  <Label htmlFor="drawer-type">Type</Label>
111
- <Select defaultValue={item.type} onValueChange={(value) => onChange(item.id, "type", value)}>
111
+ <Select defaultValue={String(item.type)} onValueChange={(value) => onChange(item.id as number, "type", value)}>
112
112
  <SelectTrigger id="drawer-type" className="w-full">
113
113
  <SelectValue placeholder="Select a type" />
114
114
  </SelectTrigger>
@@ -123,7 +123,7 @@ export function RowDetailDrawer({ item, onChange }: RowDetailDrawerProps) {
123
123
  </div>
124
124
  <div className="flex flex-col gap-3">
125
125
  <Label htmlFor="drawer-status">Status</Label>
126
- <Select defaultValue={item.status} onValueChange={(value) => onChange(item.id, "status", value)}>
126
+ <Select defaultValue={String(item.status)} onValueChange={(value) => onChange(item.id as number, "status", value)}>
127
127
  <SelectTrigger id="drawer-status" className="w-full">
128
128
  <SelectValue placeholder="Select a status" />
129
129
  </SelectTrigger>
@@ -138,16 +138,16 @@ export function RowDetailDrawer({ item, onChange }: RowDetailDrawerProps) {
138
138
  <div className="grid grid-cols-2 gap-4">
139
139
  <div className="flex flex-col gap-3">
140
140
  <Label htmlFor="drawer-target">Target</Label>
141
- <Input id="drawer-target" defaultValue={item.target} onBlur={(e) => onChange(item.id, "target", e.target.value)} />
141
+ <Input id="drawer-target" defaultValue={String(item.target)} onBlur={(e) => onChange(item.id as number, "target", e.target.value)} />
142
142
  </div>
143
143
  <div className="flex flex-col gap-3">
144
144
  <Label htmlFor="drawer-limit">Limit</Label>
145
- <Input id="drawer-limit" defaultValue={item.limit} onBlur={(e) => onChange(item.id, "limit", e.target.value)} />
145
+ <Input id="drawer-limit" defaultValue={String(item.limit)} onBlur={(e) => onChange(item.id as number, "limit", e.target.value)} />
146
146
  </div>
147
147
  </div>
148
148
  <div className="flex flex-col gap-3">
149
149
  <Label htmlFor="drawer-reviewer">Reviewer</Label>
150
- <Select defaultValue={item.reviewer} onValueChange={(value) => onChange(item.id, "reviewer", value)}>
150
+ <Select defaultValue={String(item.reviewer)} onValueChange={(value) => onChange(item.id as number, "reviewer", value)}>
151
151
  <SelectTrigger id="drawer-reviewer" className="w-full">
152
152
  <SelectValue placeholder="Select a reviewer" />
153
153
  </SelectTrigger>
@@ -13,7 +13,7 @@ export function StatusCell({ status }: StatusCellProps) {
13
13
  {status === "Done" ? <CheckCircle2 className="size-3 text-green-500" /> : null}
14
14
  {status === "In Process" ? <LoaderCircle className="size-3 animate-spin" /> : null}
15
15
  {status === "Not Started" ? <CircleSlash className="size-3" /> : null}
16
- {status}
16
+ {status as React.ReactNode}
17
17
  </Badge>
18
18
  )
19
19
  }
@@ -12,7 +12,7 @@ import {
12
12
  type SortingState,
13
13
  type VisibilityState,
14
14
  } from "@tanstack/react-table"
15
- import { arrayMove, type UniqueIdentifier } from "@dnd-kit/sortable"
15
+ import { arrayMove } from "@dnd-kit/sortable"
16
16
 
17
17
  import type { DashboardRow } from "./table-types"
18
18
 
@@ -54,7 +54,7 @@ export function useEnhancedDataTable({ data: initialData, columns, onReorder, se
54
54
  })
55
55
  }, [serverPagination])
56
56
 
57
- const dataIds = React.useMemo<UniqueIdentifier[]>(() => data.map((item) => item.id), [data])
57
+ const dataIds = React.useMemo<string[]>(() => data.map((item) => String(item.id)), [data])
58
58
 
59
59
  const table = useReactTable({
60
60
  data,
@@ -86,7 +86,7 @@ export function useEnhancedDataTable({ data: initialData, columns, onReorder, se
86
86
  })
87
87
 
88
88
  const reorderById = React.useCallback(
89
- (activeId: UniqueIdentifier, overId: UniqueIdentifier) => {
89
+ (activeId: string, overId: string) => {
90
90
  if (activeId === overId) {
91
91
  return
92
92
  }
@@ -9,7 +9,13 @@ import React from 'react'
9
9
  import { Tabs, TabsList, TabsTrigger, Button, ScrollArea } from '@/components/primitives'
10
10
  import { X, Circle } from 'lucide-react'
11
11
  import { cn } from '@/lib/utils'
12
- import type { DocumentFile } from '@/types/ai-editor'
12
+ export interface DocumentFile {
13
+ id: string
14
+ name: string
15
+ isDirty?: boolean
16
+ format?: string
17
+ lastModified?: number
18
+ }
13
19
 
14
20
  /**
15
21
  * Props for DocumentTabBar composite
@@ -70,7 +76,7 @@ export const DocumentTabBar = React.memo<DocumentTabBarProps>(
70
76
  )}
71
77
  data-slot="document-tab-bar"
72
78
  >
73
- <ScrollArea orientation="horizontal" className="flex-1">
79
+ <ScrollArea className="flex-1">
74
80
  <Tabs
75
81
  value={activeTabId || tabs[0]?.id}
76
82
  onValueChange={onTabSelect}
@@ -13,6 +13,7 @@ interface ChecklistItem {
13
13
  id: string;
14
14
  label: string;
15
15
  checked: boolean;
16
+ isTask: boolean;
16
17
  }
17
18
 
18
19
  function parseChecklistItems(content?: string) {
@@ -50,6 +51,7 @@ function parseChecklistItems(content?: string) {
50
51
  id: `checklist-${index}`,
51
52
  label: taskMatch[2],
52
53
  checked: taskMatch[1].toLowerCase() === "x",
54
+ isTask: true,
53
55
  });
54
56
  return items;
55
57
  }
@@ -61,6 +63,7 @@ function parseChecklistItems(content?: string) {
61
63
  id: `checklist-${index}`,
62
64
  label: numberStripped,
63
65
  checked: false,
66
+ isTask: false,
64
67
  });
65
68
 
66
69
  return items;
@@ -121,16 +124,18 @@ export const FilePreviewDialog = React.memo<FilePreviewDialogProps>(
121
124
  key={item.id}
122
125
  className="flex items-start gap-3 rounded-md px-1 py-1 text-sm leading-6"
123
126
  >
124
- <Checkbox
125
- checked={checkedItems[item.id] ?? false}
126
- onCheckedChange={(checked) => {
127
- setCheckedItems((prev) => ({
128
- ...prev,
129
- [item.id]: checked === true,
130
- }));
131
- }}
132
- className="mt-1"
133
- />
127
+ {item.isTask && (
128
+ <Checkbox
129
+ checked={checkedItems[item.id] ?? false}
130
+ onCheckedChange={(checked) => {
131
+ setCheckedItems((prev) => ({
132
+ ...prev,
133
+ [item.id]: checked === true,
134
+ }));
135
+ }}
136
+ className="mt-1"
137
+ />
138
+ )}
134
139
  <span>{item.label}</span>
135
140
  </label>
136
141
  ))}
@@ -15,12 +15,19 @@ import { Label } from "@/components/primitives/Label"
15
15
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/primitives/Select"
16
16
  import { Checkbox } from "@/components/primitives/Checkbox"
17
17
  import { Textarea } from "@/components/primitives/Textarea"
18
- import type {
19
- FormFieldDefinition,
20
- FormFieldOption,
21
- FormFieldType,
22
- FormFieldValue,
23
- } from "design-schema"
18
+ type FormFieldType = "text" | "number" | "date" | "textarea" | "select" | "boolean"
19
+ type FormFieldValue = string | number | boolean | null
20
+ interface FormFieldOption { value: string; label: string }
21
+ interface FormFieldDefinition {
22
+ name: string
23
+ label: string
24
+ type: FormFieldType
25
+ required?: boolean
26
+ placeholder?: string
27
+ description?: string
28
+ defaultValue?: FormFieldValue
29
+ options?: FormFieldOption[]
30
+ }
24
31
 
25
32
  export type FormReportsFieldType = FormFieldType
26
33
 
@@ -142,7 +149,7 @@ export const FormReportsDrawerForm = React.memo<FormReportsDrawerFormProps>(
142
149
  <SelectValue placeholder={field.placeholder ?? `Select ${field.label}`} />
143
150
  </SelectTrigger>
144
151
  <SelectContent>
145
- {(field.options ?? []).map((option) => (
152
+ {(field.options ?? []).map((option: FormFieldOption) => (
146
153
  <SelectItem key={option.value} value={option.value}>
147
154
  {option.label}
148
155
  </SelectItem>
@@ -9,7 +9,20 @@
9
9
 
10
10
  import type { JSONContent } from '@tiptap/core'
11
11
  import type { Annotation, User } from '@/types/ai-editor'
12
- import type { DocumentWithAnnotations, DocumentFile } from '@/types/ai-editor'
12
+
13
+ interface DocumentFile {
14
+ id: string
15
+ name: string
16
+ isDirty?: boolean
17
+ format?: string
18
+ lastModified?: number
19
+ }
20
+
21
+ interface DocumentWithAnnotations {
22
+ file: DocumentFile
23
+ content: JSONContent | string
24
+ annotations: Annotation[]
25
+ }
13
26
 
14
27
  /**
15
28
  * Sample document content for stories and tests
@@ -38,7 +38,12 @@ import { DocumentTabBar } from '@/components/composites/DocumentTabBar'
38
38
  import { cn } from '@/lib/utils'
39
39
  import type { JSONContent } from '@tiptap/core'
40
40
  import type { Annotation, User } from '@/types/ai-editor/annotations'
41
- import type { DocumentWithAnnotations } from '@/types/ai-editor'
41
+
42
+ interface DocumentWithAnnotations {
43
+ file: { id: string; name: string; isDirty?: boolean; format?: 'json' | 'markdown' | string; lastModified?: number }
44
+ content: JSONContent | string
45
+ annotations: Annotation[]
46
+ }
42
47
 
43
48
  /**
44
49
  * Props for AIDocEditor feature component - Single document mode (backward compatible)
@@ -240,7 +245,7 @@ export const AIDocEditor = React.memo<AIDocEditorProps>(
240
245
  <div className="flex-1 overflow-auto">
241
246
  <DocumentEditorWithComments
242
247
  content={currentDocument.content}
243
- format={currentDocument.file.format}
248
+ format={currentDocument.file.format as 'json' | 'markdown' | undefined}
244
249
  annotations={currentDocument.annotations}
245
250
  currentUserId={currentUser.id}
246
251
  currentUserName={currentUser.name}
@@ -6,10 +6,24 @@
6
6
  */
7
7
 
8
8
  import { useState, useCallback } from 'react'
9
+ import type { JSONContent } from '@tiptap/core'
9
10
  import type { Annotation } from '@/types/ai-editor/annotations'
10
- import type { DocumentFile, DocumentWithAnnotations } from '@/types/ai-editor'
11
11
  import type { UseAIDocEditorReturn, UseAIMultiTabDocEditorReturn } from './useAIDocEditor'
12
12
 
13
+ interface DocumentFile {
14
+ id: string
15
+ name: string
16
+ isDirty: boolean
17
+ format?: 'json' | 'markdown'
18
+ lastModified: number
19
+ }
20
+
21
+ interface DocumentWithAnnotations {
22
+ file: DocumentFile
23
+ content: JSONContent | string
24
+ annotations: Annotation[]
25
+ }
26
+
13
27
  type MultiDocMockConfig = {
14
28
  multiDoc: true
15
29
  initialDocuments?: DocumentWithAnnotations[]
@@ -76,9 +90,9 @@ function useMultiTabDocEditorMockState(
76
90
  )
77
91
  const [loading, setLoading] = useState(false)
78
92
 
79
- const addDocument = useCallback((file: DocumentFile, content: any) => {
93
+ const addDocument = useCallback((file: DocumentFile, content: unknown) => {
80
94
  console.log('[Multi-Tab Mock] Adding document:', file.name)
81
- setDocuments(prev => [...prev, { file, content, annotations: [] }])
95
+ setDocuments(prev => [...prev, { file, content: content as JSONContent | string, annotations: [] }])
82
96
  setActiveDocumentId(file.id)
83
97
  }, [])
84
98
 
@@ -227,6 +241,6 @@ export function useAIDocEditorMock(
227
241
  * @param initialDocuments - Initial documents to display
228
242
  * @returns Mock implementation of UseAIMultiTabDocEditorReturn
229
243
  */
230
- export function useAIMultiTabDocEditorMock(initialDocuments: any[] = []): UseAIMultiTabDocEditorReturn {
244
+ export function useAIMultiTabDocEditorMock(initialDocuments: unknown[] = []): UseAIMultiTabDocEditorReturn {
231
245
  return useMultiTabDocEditorMockState(initialDocuments as DocumentWithAnnotations[])
232
246
  }
@@ -1,9 +1,9 @@
1
1
  import type { DashboardRow } from "@/components/composites/DataTable"
2
- import {
3
- formSchema,
4
- type FormFieldDefinition,
5
- type FormSchema,
6
- } from "design-schema/schemas/form"
2
+ import type { FormReportsFieldDefinition } from "@/components/composites/FormReports"
3
+
4
+ const formSchema = {
5
+ parse<T>(input: T): T { return input },
6
+ } as const
7
7
  import {
8
8
  DYNAMIC_TABLE_SCHEMA_VERSION,
9
9
  FORM_SCHEMA_VERSION,
@@ -154,9 +154,9 @@ const dashboardCreateFormSchemaInput = {
154
154
  placeholder: "Enable immediately",
155
155
  },
156
156
  ],
157
- } satisfies FormSchema
157
+ }
158
158
 
159
- export const dashboardCreateFields: FormFieldDefinition[] = formSchema.parse(dashboardCreateFormSchemaInput).fields
159
+ export const dashboardCreateFields: FormReportsFieldDefinition[] = formSchema.parse(dashboardCreateFormSchemaInput).fields as unknown as FormReportsFieldDefinition[]
160
160
 
161
161
  export const dashboardKpis = [
162
162
  {
@@ -4,10 +4,6 @@ import type {
4
4
  FormReportsFieldDefinition,
5
5
  FormReportsRowAction,
6
6
  } from "@/components/composites/FormReports"
7
- import {
8
- formSchema,
9
- type FormSchema,
10
- } from "design-schema/schemas/form"
11
7
  import {
12
8
  DYNAMIC_TABLE_SCHEMA_VERSION,
13
9
  FORM_SCHEMA_VERSION,
@@ -15,59 +11,24 @@ import {
15
11
  type DynamicTableSchema,
16
12
  } from "ui-schema-contracts"
17
13
 
14
+ const formSchema = {
15
+ parse<T>(input: T): T { return input },
16
+ }
17
+
18
18
  export const formReportsEntityName = "Feature Flag"
19
19
 
20
20
  const formReportsFormSchemaInput = {
21
21
  schemaVersion: FORM_SCHEMA_VERSION,
22
22
  fields: [
23
- {
24
- name: "slug",
25
- label: "Slug",
26
- type: "text",
27
- required: true,
28
- placeholder: "my-flag",
29
- description: "Unique identifier for this entity.",
30
- },
31
- {
32
- name: "project",
33
- label: "Project",
34
- type: "select",
35
- placeholder: "Select project",
36
- options: [
37
- { label: "Website", value: "website" },
38
- { label: "Dashboard", value: "dashboard" },
39
- { label: "Mobile App", value: "mobile" },
40
- ],
41
- },
42
- {
43
- name: "description",
44
- label: "Description",
45
- type: "textarea",
46
- placeholder: "Describe what this entity controls...",
47
- },
48
- {
49
- name: "type",
50
- label: "Type",
51
- type: "select",
52
- defaultValue: "boolean",
53
- options: [
54
- { label: "Boolean", value: "boolean" },
55
- { label: "String", value: "string" },
56
- { label: "Number", value: "number" },
57
- { label: "JSON", value: "json" },
58
- ],
59
- },
60
- {
61
- name: "enabled",
62
- label: "Enabled",
63
- type: "boolean",
64
- defaultValue: true,
65
- placeholder: "Enable immediately",
66
- },
23
+ { name: "slug", label: "Slug", type: "text", required: true, placeholder: "my-flag", description: "Unique identifier for this entity." },
24
+ { name: "project", label: "Project", type: "select", placeholder: "Select project", options: [{ label: "Website", value: "website" }, { label: "Dashboard", value: "dashboard" }, { label: "Mobile App", value: "mobile" }] },
25
+ { name: "description", label: "Description", type: "textarea", placeholder: "Describe what this entity controls..." },
26
+ { name: "type", label: "Type", type: "select", defaultValue: "boolean", options: [{ label: "Boolean", value: "boolean" }, { label: "String", value: "string" }, { label: "Number", value: "number" }, { label: "JSON", value: "json" }] },
27
+ { name: "enabled", label: "Enabled", type: "boolean", defaultValue: true, placeholder: "Enable immediately" },
67
28
  ],
68
- } satisfies FormSchema
29
+ }
69
30
 
70
- export const formReportsFields: FormReportsFieldDefinition[] = formSchema.parse(formReportsFormSchemaInput).fields
31
+ export const formReportsFields: FormReportsFieldDefinition[] = formSchema.parse(formReportsFormSchemaInput).fields as unknown as FormReportsFieldDefinition[]
71
32
 
72
33
  const formReportsTableSchemaInput = {
73
34
  schemaVersion: DYNAMIC_TABLE_SCHEMA_VERSION,
@@ -66,7 +66,7 @@ export function useRefinementPanelMock(
66
66
  }, [reviewMessages, reviewFileChanges, apiDelay]);
67
67
 
68
68
  const onSubmit = useCallback(async (message: PromptInputMessage, _event: FormEvent<HTMLFormElement>) => {
69
- await handleSubmit(message.text);
69
+ await handleSubmit(message.text || '');
70
70
  }, [handleSubmit]);
71
71
 
72
72
  // Simulate approval: clear file changes and add success message
@@ -1,12 +1,24 @@
1
1
  import * as React from "react";
2
- import {
3
- FilePreviewDialog,
4
- FileQueue,
5
- type FileGroup,
6
- type FileItem,
7
- } from "@/components/composites";
2
+ import { FilePreviewDialog, FileQueue } from "@/components/composites";
8
3
  import { cn } from "@/lib/utils";
9
4
 
5
+ interface FileItem {
6
+ id: string;
7
+ name: string;
8
+ path?: string;
9
+ icon?: string;
10
+ iconColor?: string;
11
+ }
12
+
13
+ interface FileGroup {
14
+ id: string;
15
+ title: string;
16
+ icon?: string;
17
+ iconColor?: string;
18
+ files: FileItem[];
19
+ defaultOpen?: boolean;
20
+ }
21
+
10
22
  /**
11
23
  * SpecNavigator Feature
12
24
  *
@@ -14,17 +26,28 @@ import { cn } from "@/lib/utils";
14
26
  * Uses FileQueue block for rendering grouped file lists.
15
27
  */
16
28
 
17
- export interface SpecNavigatorFile extends FileItem {
18
- /** Optional markdown content rendered in the preview dialog */
19
- previewContent?: string;
29
+ export interface SpecNavigatorFile {
20
30
  /** Optional dialog title override */
21
31
  previewTitle?: string;
22
32
  /** Optional dialog subtitle or path description */
23
33
  previewDescription?: string;
34
+ /** Optional markdown content rendered in the preview dialog */
35
+ previewContent?: string;
36
+ /** Unique identifier */
37
+ id: string;
38
+ /** File name (shown as label) */
39
+ name: string;
40
+ /** File path prefix (shown as secondary info) */
41
+ path?: string;
24
42
  }
25
43
 
26
- export interface SpecNavigatorGroup extends Omit<FileGroup, "files"> {
44
+ export interface SpecNavigatorGroup {
45
+ id: string;
46
+ title: string;
47
+ icon?: string;
48
+ iconColor?: string;
27
49
  files: SpecNavigatorFile[];
50
+ defaultOpen?: boolean;
28
51
  }
29
52
 
30
53
  /**