ai-design-system 0.1.0
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/README.md +307 -0
- package/components/ai-elements/actions.tsx +65 -0
- package/components/ai-elements/artifact.tsx +147 -0
- package/components/ai-elements/branch.tsx +212 -0
- package/components/ai-elements/canvas.tsx +24 -0
- package/components/ai-elements/chain-of-thought.tsx +228 -0
- package/components/ai-elements/code-block.tsx +179 -0
- package/components/ai-elements/confirmation.tsx +169 -0
- package/components/ai-elements/connection.tsx +28 -0
- package/components/ai-elements/context.tsx +408 -0
- package/components/ai-elements/controls.tsx +18 -0
- package/components/ai-elements/conversation.tsx +97 -0
- package/components/ai-elements/edge.tsx +140 -0
- package/components/ai-elements/image.tsx +24 -0
- package/components/ai-elements/inline-citation.tsx +287 -0
- package/components/ai-elements/loader.tsx +96 -0
- package/components/ai-elements/message.tsx +80 -0
- package/components/ai-elements/node.tsx +71 -0
- package/components/ai-elements/open-in-chat.tsx +363 -0
- package/components/ai-elements/panel.tsx +15 -0
- package/components/ai-elements/plan.tsx +142 -0
- package/components/ai-elements/prompt-input.tsx +1352 -0
- package/components/ai-elements/queue.tsx +274 -0
- package/components/ai-elements/reasoning.tsx +178 -0
- package/components/ai-elements/response.tsx +22 -0
- package/components/ai-elements/shimmer.tsx +64 -0
- package/components/ai-elements/sources.tsx +77 -0
- package/components/ai-elements/suggestion.tsx +56 -0
- package/components/ai-elements/task.tsx +87 -0
- package/components/ai-elements/tool.tsx +179 -0
- package/components/ai-elements/toolbar.tsx +16 -0
- package/components/ai-elements/web-preview.tsx +263 -0
- package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
- package/components/blocks/AIConversation/AIConversation.tsx +186 -0
- package/components/blocks/AIConversation/index.ts +8 -0
- package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
- package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
- package/components/blocks/AppSidebar/index.ts +2 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
- package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
- package/components/blocks/FileChangeQueue/index.ts +7 -0
- package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
- package/components/blocks/LayoutProvider/index.ts +1 -0
- package/components/blocks/index.ts +2 -0
- package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
- package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
- package/components/composites/AgentIndicator/index.ts +8 -0
- package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
- package/components/composites/AppHeader/AppHeader.tsx +24 -0
- package/components/composites/AppHeader/index.ts +2 -0
- package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
- package/components/composites/CommentBox/CommentBox.tsx +364 -0
- package/components/composites/CommentBox/index.ts +8 -0
- package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
- package/components/composites/Confirmation/Confirmation.tsx +93 -0
- package/components/composites/Confirmation/index.ts +7 -0
- package/components/composites/DataTable/DataTable.stories.tsx +35 -0
- package/components/composites/DataTable/DataTable.tsx +95 -0
- package/components/composites/DataTable/index.ts +2 -0
- package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
- package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
- package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
- package/components/composites/DocumentEditor/index.ts +8 -0
- package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
- package/components/composites/FileQueue/FileQueue.tsx +161 -0
- package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
- package/components/composites/FileQueue/index.ts +24 -0
- package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
- package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
- package/components/composites/InteractiveChart/index.ts +2 -0
- package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
- package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
- package/components/composites/ModeToggle/index.ts +7 -0
- package/components/composites/NavUser/NavUser.stories.tsx +50 -0
- package/components/composites/NavUser/NavUser.tsx +60 -0
- package/components/composites/NavUser/index.ts +2 -0
- package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
- package/components/composites/NavigationList/NavigationList.tsx +46 -0
- package/components/composites/NavigationList/index.ts +2 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
- package/components/composites/OrchestratorMessage/index.ts +8 -0
- package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
- package/components/composites/PageContainer/PageContainer.tsx +24 -0
- package/components/composites/PageContainer/index.ts +2 -0
- package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
- package/components/composites/PromptInput/PromptInput.tsx +129 -0
- package/components/composites/PromptInput/index.ts +8 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
- package/components/composites/SpecialistMessage/index.ts +8 -0
- package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
- package/components/composites/StatsCard/StatsCard.tsx +81 -0
- package/components/composites/StatsCard/index.ts +2 -0
- package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
- package/components/composites/TablePagination/TablePagination.tsx +119 -0
- package/components/composites/TablePagination/index.ts +2 -0
- package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
- package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
- package/components/composites/TableToolbar/index.ts +2 -0
- package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
- package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
- package/components/composites/ThemeSelector/index.ts +2 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
- package/components/composites/ToolCallDisplay/index.ts +8 -0
- package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
- package/components/composites/UserMessage/UserMessage.tsx +52 -0
- package/components/composites/UserMessage/index.ts +8 -0
- package/components/composites/index.ts +90 -0
- package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
- package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
- package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
- package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
- package/components/features/AIDocEditor/index.ts +8 -0
- package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
- package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
- package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
- package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
- package/components/features/PageLayout/PageLayout.tsx +94 -0
- package/components/features/PageLayout/index.ts +4 -0
- package/components/features/PageLayout/usePageLayout.d.ts +24 -0
- package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
- package/components/features/RefinementPanel/README.md +189 -0
- package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
- package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
- package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
- package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
- package/components/features/RefinementPanel/index.ts +25 -0
- package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
- package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
- package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
- package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
- package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
- package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
- package/components/features/SpecNavigator/index.ts +2 -0
- package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
- package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
- package/components/features/index.ts +18 -0
- package/components/index.ts +14 -0
- package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
- package/components/primitives/Accordion/Accordion.tsx +66 -0
- package/components/primitives/Accordion/index.ts +13 -0
- package/components/primitives/Alert/Alert.stories.tsx +422 -0
- package/components/primitives/Alert/Alert.tsx +61 -0
- package/components/primitives/Alert/index.ts +8 -0
- package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
- package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
- package/components/primitives/AlertDialog/index.ts +25 -0
- package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
- package/components/primitives/Avatar/Avatar.tsx +63 -0
- package/components/primitives/Avatar/index.ts +8 -0
- package/components/primitives/Badge/Badge.stories.tsx +74 -0
- package/components/primitives/Badge/Badge.tsx +49 -0
- package/components/primitives/Badge/index.ts +2 -0
- package/components/primitives/Button/Button.stories.tsx +445 -0
- package/components/primitives/Button/Button.tsx +89 -0
- package/components/primitives/Button/index.ts +7 -0
- package/components/primitives/Card/Card.stories.tsx +831 -0
- package/components/primitives/Card/Card.tsx +242 -0
- package/components/primitives/Card/index.ts +30 -0
- package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
- package/components/primitives/Carousel/Carousel.tsx +63 -0
- package/components/primitives/Carousel/index.ts +13 -0
- package/components/primitives/Chart/Chart.stories.tsx +346 -0
- package/components/primitives/Chart/Chart.tsx +117 -0
- package/components/primitives/Chart/index.ts +20 -0
- package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
- package/components/primitives/Checkbox/Checkbox.tsx +38 -0
- package/components/primitives/Checkbox/index.ts +2 -0
- package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
- package/components/primitives/Collapsible/Collapsible.tsx +39 -0
- package/components/primitives/Collapsible/index.ts +8 -0
- package/components/primitives/Command/Command.stories.tsx +150 -0
- package/components/primitives/Command/Command.tsx +147 -0
- package/components/primitives/Command/index.ts +20 -0
- package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
- package/components/primitives/Dialog/Dialog.tsx +140 -0
- package/components/primitives/Dialog/index.ts +22 -0
- package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
- package/components/primitives/Drawer/Drawer.tsx +208 -0
- package/components/primitives/Drawer/index.ts +27 -0
- package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
- package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
- package/components/primitives/DropdownMenu/index.ts +1 -0
- package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
- package/components/primitives/HoverCard/HoverCard.tsx +39 -0
- package/components/primitives/HoverCard/index.ts +8 -0
- package/components/primitives/Icon/Icon.stories.tsx +281 -0
- package/components/primitives/Icon/Icon.tsx +87 -0
- package/components/primitives/Icon/index.ts +8 -0
- package/components/primitives/Input/Input.stories.tsx +370 -0
- package/components/primitives/Input/Input.tsx +88 -0
- package/components/primitives/Input/index.ts +7 -0
- package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
- package/components/primitives/InputGroup/InputGroup.tsx +72 -0
- package/components/primitives/InputGroup/index.ts +14 -0
- package/components/primitives/Label/Label.stories.tsx +227 -0
- package/components/primitives/Label/Label.tsx +53 -0
- package/components/primitives/Label/index.ts +7 -0
- package/components/primitives/Popover/Popover.stories.tsx +42 -0
- package/components/primitives/Popover/Popover.tsx +107 -0
- package/components/primitives/Popover/index.ts +2 -0
- package/components/primitives/Progress/Progress.stories.tsx +340 -0
- package/components/primitives/Progress/Progress.tsx +31 -0
- package/components/primitives/Progress/index.ts +1 -0
- package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
- package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
- package/components/primitives/ScrollArea/index.ts +6 -0
- package/components/primitives/Select/Select.stories.tsx +288 -0
- package/components/primitives/Select/Select.tsx +162 -0
- package/components/primitives/Select/index.ts +22 -0
- package/components/primitives/Separator/Separator.stories.tsx +264 -0
- package/components/primitives/Separator/Separator.tsx +48 -0
- package/components/primitives/Separator/index.ts +7 -0
- package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
- package/components/primitives/Sidebar/Sidebar.tsx +317 -0
- package/components/primitives/Sidebar/index.ts +41 -0
- package/components/primitives/Table/Table.stories.tsx +389 -0
- package/components/primitives/Table/Table.tsx +191 -0
- package/components/primitives/Table/index.ts +26 -0
- package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
- package/components/primitives/Tabs/Tabs.tsx +70 -0
- package/components/primitives/Tabs/index.ts +13 -0
- package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
- package/components/primitives/Textarea/Textarea.tsx +91 -0
- package/components/primitives/Textarea/index.ts +7 -0
- package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
- package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
- package/components/primitives/ToggleGroup/index.ts +6 -0
- package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
- package/components/primitives/Tooltip/Tooltip.tsx +78 -0
- package/components/primitives/Tooltip/index.ts +10 -0
- package/components/primitives/index.ts +34 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +157 -0
- package/components/ui/alert.tsx +66 -0
- package/components/ui/avatar.tsx +53 -0
- package/components/ui/badge.tsx +46 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/card.tsx +117 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +334 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +184 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/drawer.tsx +118 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/input-group.tsx +170 -0
- package/components/ui/input.tsx +48 -0
- package/components/ui/label.tsx +26 -0
- package/components/ui/popover.tsx +33 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/select.tsx +187 -0
- package/components/ui/separator.tsx +31 -0
- package/components/ui/sidebar.tsx +577 -0
- package/components/ui/table.tsx +120 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +46 -0
- package/components/ui/toggle-group.tsx +83 -0
- package/components/ui/toggle.tsx +47 -0
- package/components/ui/tooltip.tsx +61 -0
- package/dist/index.cjs +7389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +75 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +7160 -0
- package/dist/index.js.map +1 -0
- package/hooks/useAIDocReviewer.d.ts +0 -0
- package/lib/utils.ts +6 -0
- package/package.json +140 -0
- package/tokens/color/base.json +14 -0
- package/tokens/color/dark.json +40 -0
- package/tokens/color/green.json +21 -0
- package/tokens/color/light.json +52 -0
- package/tokens/color/neutral.json +20 -0
- package/tokens/color/violet.json +21 -0
- package/tokens/spacing.json +22 -0
- package/utils/ai-editor/format-date.ts +41 -0
- package/utils/ai-editor/index.ts +22 -0
- package/utils/ai-editor/type-guards.ts +72 -0
- package/utils/ai-editor/validation.ts +130 -0
- package/utils/editor-annotations.ts +122 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocks
|
|
3
|
+
*
|
|
4
|
+
* Central export point for all block components.
|
|
5
|
+
* Blocks are composite components that extend AI elements with enhanced functionality.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ToolCallDisplay Block
|
|
9
|
+
export { ToolCallDisplay } from './ToolCallDisplay'
|
|
10
|
+
export type { ToolCallDisplayProps, ToolCall } from './ToolCallDisplay'
|
|
11
|
+
|
|
12
|
+
// AgentIndicator Block
|
|
13
|
+
export { AgentIndicator } from './AgentIndicator'
|
|
14
|
+
export type { AgentIndicatorProps, SubAgent } from './AgentIndicator'
|
|
15
|
+
|
|
16
|
+
// UserMessage Block
|
|
17
|
+
export { UserMessage } from './UserMessage'
|
|
18
|
+
export type { UserMessageProps, UserMessageData } from './UserMessage'
|
|
19
|
+
|
|
20
|
+
// SpecialistMessage Block
|
|
21
|
+
export { SpecialistMessage } from './SpecialistMessage'
|
|
22
|
+
export type { SpecialistMessageProps, SpecialistMessageData } from './SpecialistMessage'
|
|
23
|
+
|
|
24
|
+
// OrchestratorMessage Block
|
|
25
|
+
export { OrchestratorMessage } from './OrchestratorMessage'
|
|
26
|
+
export type { OrchestratorMessageProps, OrchestratorMessageData } from './OrchestratorMessage'
|
|
27
|
+
|
|
28
|
+
// PromptInput Block
|
|
29
|
+
export { PromptInput } from './PromptInput'
|
|
30
|
+
export type { PromptInputBlockProps } from './PromptInput'
|
|
31
|
+
|
|
32
|
+
// FileQueue Block
|
|
33
|
+
export { FileQueue, FileStatusBadge } from './FileQueue'
|
|
34
|
+
export type { FileQueueProps, FileChangeData, FileStatusBadgeProps, FileStatus } from './FileQueue'
|
|
35
|
+
|
|
36
|
+
// Confirmation Block
|
|
37
|
+
export { Confirmation } from './Confirmation'
|
|
38
|
+
export type { ConfirmationProps } from './Confirmation'
|
|
39
|
+
|
|
40
|
+
// CommentBox Block
|
|
41
|
+
export { CommentBox } from './CommentBox'
|
|
42
|
+
export type { CommentBoxProps } from '@/types/ai-editor'
|
|
43
|
+
|
|
44
|
+
// DocumentEditor Block
|
|
45
|
+
export { DocumentEditor } from './DocumentEditor'
|
|
46
|
+
export type { DocumentEditorProps } from '@/types/ai-editor'
|
|
47
|
+
|
|
48
|
+
// ModeToggle Composite
|
|
49
|
+
export { ModeToggle } from './ModeToggle'
|
|
50
|
+
export type { ModeToggleProps } from './ModeToggle'
|
|
51
|
+
|
|
52
|
+
// ThemeSelector Composite
|
|
53
|
+
export { ThemeSelector } from './ThemeSelector'
|
|
54
|
+
export type { ThemeSelectorProps, Theme } from './ThemeSelector'
|
|
55
|
+
|
|
56
|
+
// TablePagination Composite
|
|
57
|
+
export { TablePagination } from './TablePagination'
|
|
58
|
+
export type { TablePaginationProps } from './TablePagination'
|
|
59
|
+
|
|
60
|
+
// TableToolbar Composite
|
|
61
|
+
export { TableToolbar } from './TableToolbar'
|
|
62
|
+
export type { TableToolbarProps } from './TableToolbar'
|
|
63
|
+
|
|
64
|
+
// StatsCard Composite
|
|
65
|
+
export { StatsCard } from './StatsCard'
|
|
66
|
+
export type { StatsCardProps } from './StatsCard'
|
|
67
|
+
|
|
68
|
+
// NavigationList Composite
|
|
69
|
+
export { NavigationList } from './NavigationList'
|
|
70
|
+
export type { NavigationListProps, NavigationItem } from './NavigationList'
|
|
71
|
+
|
|
72
|
+
// NavUser Composite
|
|
73
|
+
export { NavUser } from './NavUser'
|
|
74
|
+
export type { NavUserProps } from './NavUser'
|
|
75
|
+
|
|
76
|
+
// AppHeader Composite
|
|
77
|
+
export { AppHeader } from './AppHeader'
|
|
78
|
+
export type { AppHeaderProps } from './AppHeader'
|
|
79
|
+
|
|
80
|
+
// InteractiveChart Composite
|
|
81
|
+
export { InteractiveChart } from './InteractiveChart'
|
|
82
|
+
export type { InteractiveChartProps } from './InteractiveChart'
|
|
83
|
+
|
|
84
|
+
// DataTable Composite
|
|
85
|
+
export { DataTable } from './DataTable'
|
|
86
|
+
export type { DataTableProps } from './DataTable'
|
|
87
|
+
|
|
88
|
+
// PageContainer Composite
|
|
89
|
+
export { PageContainer } from './PageContainer'
|
|
90
|
+
export type { PageContainerProps } from './PageContainer'
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIDocEditor Behavior Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests user interactions and state changes to prevent regressions.
|
|
5
|
+
* These tests validate functionality, not visual appearance.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
9
|
+
import { expect, fn, userEvent, within, waitFor, screen } from '@storybook/test'
|
|
10
|
+
import type { Annotation } from '@/types/ai-editor'
|
|
11
|
+
import { AIDocEditor } from './AIDocEditor'
|
|
12
|
+
import { currentUser, sampleAnnotations, sampleContent } from './AIDocEditor.mocks'
|
|
13
|
+
|
|
14
|
+
const meta: Meta<typeof AIDocEditor> = {
|
|
15
|
+
title: 'Features/AIDocEditor/Behaviors',
|
|
16
|
+
component: AIDocEditor,
|
|
17
|
+
tags: ['test'],
|
|
18
|
+
parameters: {
|
|
19
|
+
layout: 'fullscreen',
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default meta
|
|
24
|
+
type Story = StoryObj<typeof AIDocEditor>
|
|
25
|
+
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// CRITICAL PRIORITY TESTS (100% coverage required)
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Test: Click annotation opens CommentBox with thread
|
|
32
|
+
* Verifies that clicking an existing annotation displays the comment thread
|
|
33
|
+
*/
|
|
34
|
+
export const ClickAnnotationOpensCommentBox: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
content: sampleContent,
|
|
37
|
+
annotations: sampleAnnotations,
|
|
38
|
+
currentUser,
|
|
39
|
+
mode: 'review',
|
|
40
|
+
onAnnotationClick: fn(),
|
|
41
|
+
onAnnotationAdd: fn(),
|
|
42
|
+
onAnnotationUpdate: fn(),
|
|
43
|
+
},
|
|
44
|
+
play: async ({ canvasElement, args }) => {
|
|
45
|
+
const canvas = within(canvasElement)
|
|
46
|
+
|
|
47
|
+
// Wait for document to render
|
|
48
|
+
await waitFor(() => {
|
|
49
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Find and click the annotation (look for highlighted text)
|
|
53
|
+
// The annotation is on "t with various annot" based on sampleAnnotations
|
|
54
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
55
|
+
await userEvent.click(annotatedText)
|
|
56
|
+
|
|
57
|
+
// Verify CommentBox appears with the comment thread
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
expect(canvas.getByText(/t with various annot/i)).toBeVisible()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Verify reply input is present
|
|
63
|
+
await waitFor(() => {
|
|
64
|
+
expect(screen.getByPlaceholderText("Reply...")).toBeInTheDocument()
|
|
65
|
+
})
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Test: Reply to comment adds to thread
|
|
71
|
+
* Verifies that adding a reply calls onAnnotationUpdate with updated thread
|
|
72
|
+
*/
|
|
73
|
+
export const ReplyToCommentAddsToThread: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
content: sampleContent,
|
|
76
|
+
annotations: sampleAnnotations,
|
|
77
|
+
currentUser,
|
|
78
|
+
mode: 'review',
|
|
79
|
+
onAnnotationClick: fn(),
|
|
80
|
+
onAnnotationAdd: fn(),
|
|
81
|
+
onAnnotationUpdate: fn(),
|
|
82
|
+
},
|
|
83
|
+
play: async ({ canvasElement, args }) => {
|
|
84
|
+
const canvas = within(canvasElement)
|
|
85
|
+
|
|
86
|
+
// Wait for document to render
|
|
87
|
+
await waitFor(() => {
|
|
88
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Click annotation to open CommentBox
|
|
92
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
93
|
+
await userEvent.click(annotatedText)
|
|
94
|
+
|
|
95
|
+
// Wait for CommentBox and reply input
|
|
96
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
97
|
+
|
|
98
|
+
// Type a reply
|
|
99
|
+
await userEvent.type(replyInput, 'I agree, this needs more detail')
|
|
100
|
+
|
|
101
|
+
// Submit reply with Enter key
|
|
102
|
+
await userEvent.keyboard('{Enter}')
|
|
103
|
+
|
|
104
|
+
// Verify onAnnotationUpdate was called
|
|
105
|
+
await waitFor(() => {
|
|
106
|
+
expect(args.onAnnotationUpdate).toHaveBeenCalled()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Verify the updated annotation has the new comment in thread
|
|
110
|
+
await waitFor(() => {
|
|
111
|
+
if (args.onAnnotationUpdate) {
|
|
112
|
+
const mockFn = args.onAnnotationUpdate as ReturnType<typeof fn>
|
|
113
|
+
const calls = mockFn.mock.calls
|
|
114
|
+
expect(calls.length).toBeGreaterThan(0)
|
|
115
|
+
const updatedAnnotation = calls[0][0] as Annotation
|
|
116
|
+
expect(updatedAnnotation.data.thread.length).toBe(2) // Original + reply
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// HIGH PRIORITY TESTS (90% coverage required)
|
|
124
|
+
// ============================================================================
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Test: ESC key closes CommentBox
|
|
128
|
+
* Verifies that pressing ESC closes an open CommentBox
|
|
129
|
+
*/
|
|
130
|
+
export const EscKeyClosesCommentBox: Story = {
|
|
131
|
+
args: {
|
|
132
|
+
content: sampleContent,
|
|
133
|
+
annotations: sampleAnnotations,
|
|
134
|
+
currentUser,
|
|
135
|
+
mode: 'review',
|
|
136
|
+
onAnnotationClick: fn(),
|
|
137
|
+
onAnnotationAdd: fn(),
|
|
138
|
+
onAnnotationUpdate: fn(),
|
|
139
|
+
},
|
|
140
|
+
play: async ({ canvasElement, args }) => {
|
|
141
|
+
const canvas = within(canvasElement)
|
|
142
|
+
|
|
143
|
+
// Wait for document to render
|
|
144
|
+
await waitFor(() => {
|
|
145
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
// Click annotation to open CommentBox
|
|
149
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
150
|
+
await userEvent.click(annotatedText)
|
|
151
|
+
|
|
152
|
+
// Wait for CommentBox to appear
|
|
153
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
154
|
+
expect(replyInput).toBeVisible()
|
|
155
|
+
|
|
156
|
+
// Press ESC key
|
|
157
|
+
await userEvent.keyboard('{Escape}')
|
|
158
|
+
|
|
159
|
+
// Verify CommentBox is closed (reply input should not be visible)
|
|
160
|
+
await waitFor(() => {
|
|
161
|
+
expect(screen.queryByPlaceholderText("Reply...")).not.toBeInTheDocument()
|
|
162
|
+
})
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Test: Enter key submits reply
|
|
168
|
+
* Verifies that pressing Enter submits a reply without Shift
|
|
169
|
+
*/
|
|
170
|
+
export const EnterKeySubmitsReply: Story = {
|
|
171
|
+
args: {
|
|
172
|
+
content: sampleContent,
|
|
173
|
+
annotations: sampleAnnotations,
|
|
174
|
+
currentUser,
|
|
175
|
+
mode: 'review',
|
|
176
|
+
onAnnotationClick: fn(),
|
|
177
|
+
onAnnotationAdd: fn(),
|
|
178
|
+
onAnnotationUpdate: fn(),
|
|
179
|
+
},
|
|
180
|
+
play: async ({ canvasElement, args }) => {
|
|
181
|
+
const canvas = within(canvasElement)
|
|
182
|
+
|
|
183
|
+
// Wait for document to render
|
|
184
|
+
await waitFor(() => {
|
|
185
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
// Click annotation to open CommentBox
|
|
189
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
190
|
+
await userEvent.click(annotatedText)
|
|
191
|
+
|
|
192
|
+
// Wait for CommentBox and reply input
|
|
193
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
194
|
+
|
|
195
|
+
// Type a reply
|
|
196
|
+
await userEvent.type(replyInput, 'Test reply')
|
|
197
|
+
|
|
198
|
+
// Submit with Enter key
|
|
199
|
+
await userEvent.keyboard('{Enter}')
|
|
200
|
+
|
|
201
|
+
// Verify onAnnotationUpdate was called
|
|
202
|
+
await waitFor(() => {
|
|
203
|
+
expect(args.onAnnotationUpdate).toHaveBeenCalled()
|
|
204
|
+
})
|
|
205
|
+
},
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Test: Shift+Enter adds line break without submitting
|
|
210
|
+
* Verifies that Shift+Enter inserts a line break instead of submitting
|
|
211
|
+
*/
|
|
212
|
+
export const ShiftEnterAddsLineBreak: Story = {
|
|
213
|
+
args: {
|
|
214
|
+
content: sampleContent,
|
|
215
|
+
annotations: sampleAnnotations,
|
|
216
|
+
currentUser,
|
|
217
|
+
mode: 'review',
|
|
218
|
+
onAnnotationClick: fn(),
|
|
219
|
+
onAnnotationAdd: fn(),
|
|
220
|
+
onAnnotationUpdate: fn(),
|
|
221
|
+
},
|
|
222
|
+
play: async ({ canvasElement, args }) => {
|
|
223
|
+
const canvas = within(canvasElement)
|
|
224
|
+
|
|
225
|
+
// Wait for document to render
|
|
226
|
+
await waitFor(() => {
|
|
227
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
// Click annotation to open CommentBox
|
|
231
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
232
|
+
await userEvent.click(annotatedText)
|
|
233
|
+
|
|
234
|
+
// Wait for CommentBox and reply input
|
|
235
|
+
const replyInput = await screen.findByPlaceholderText("Reply...") as HTMLTextAreaElement
|
|
236
|
+
|
|
237
|
+
// Type first line
|
|
238
|
+
await userEvent.type(replyInput, 'First line')
|
|
239
|
+
|
|
240
|
+
// Press Shift+Enter to add line break
|
|
241
|
+
await userEvent.keyboard('{Shift>}{Enter}{/Shift}')
|
|
242
|
+
|
|
243
|
+
// Type second line
|
|
244
|
+
await userEvent.type(replyInput, 'Second line')
|
|
245
|
+
|
|
246
|
+
// Verify onAnnotationUpdate was NOT called yet (Shift+Enter doesn't submit)
|
|
247
|
+
expect(args.onAnnotationUpdate).not.toHaveBeenCalled()
|
|
248
|
+
|
|
249
|
+
// Verify textarea contains both lines with line break
|
|
250
|
+
expect(replyInput.value).toContain('First line\nSecond line')
|
|
251
|
+
},
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// MEDIUM PRIORITY TESTS (75% coverage required)
|
|
256
|
+
// ============================================================================
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Test: CommentBox positions near annotation
|
|
260
|
+
* Verifies that CommentBox appears within viewport when annotation is clicked
|
|
261
|
+
*/
|
|
262
|
+
export const CommentBoxPositionsNearAnnotation: Story = {
|
|
263
|
+
args: {
|
|
264
|
+
content: sampleContent,
|
|
265
|
+
annotations: sampleAnnotations,
|
|
266
|
+
currentUser,
|
|
267
|
+
mode: 'review',
|
|
268
|
+
onAnnotationClick: fn(),
|
|
269
|
+
onAnnotationAdd: fn(),
|
|
270
|
+
onAnnotationUpdate: fn(),
|
|
271
|
+
},
|
|
272
|
+
play: async ({ canvasElement, args }) => {
|
|
273
|
+
const canvas = within(canvasElement)
|
|
274
|
+
|
|
275
|
+
// Wait for document to render
|
|
276
|
+
await waitFor(() => {
|
|
277
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
// Click annotation to open CommentBox
|
|
281
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
282
|
+
await userEvent.click(annotatedText)
|
|
283
|
+
|
|
284
|
+
// Wait for CommentBox to appear
|
|
285
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
286
|
+
|
|
287
|
+
// Verify CommentBox is visible (within viewport)
|
|
288
|
+
expect(replyInput).toBeVisible()
|
|
289
|
+
|
|
290
|
+
// Verify CommentBox has position styling (absolute positioning)
|
|
291
|
+
const popoverContent = replyInput.closest('[role="dialog"]') || replyInput.closest('.popover-content')
|
|
292
|
+
expect(popoverContent).toBeInTheDocument()
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Test: Readonly mode disables interactions
|
|
298
|
+
* Verifies that readonly mode prevents comment creation
|
|
299
|
+
*/
|
|
300
|
+
export const ReadonlyModeDisablesInteractions: Story = {
|
|
301
|
+
args: {
|
|
302
|
+
content: sampleContent,
|
|
303
|
+
annotations: sampleAnnotations,
|
|
304
|
+
currentUser,
|
|
305
|
+
mode: 'readonly',
|
|
306
|
+
onAnnotationClick: fn(),
|
|
307
|
+
onAnnotationAdd: fn(),
|
|
308
|
+
onAnnotationUpdate: fn(),
|
|
309
|
+
},
|
|
310
|
+
play: async ({ canvasElement, args }) => {
|
|
311
|
+
const canvas = within(canvasElement)
|
|
312
|
+
|
|
313
|
+
// Wait for document to render
|
|
314
|
+
await waitFor(() => {
|
|
315
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
// Click annotation to open CommentBox (should still work in readonly)
|
|
319
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
320
|
+
await userEvent.click(annotatedText)
|
|
321
|
+
|
|
322
|
+
// Wait for CommentBox to appear
|
|
323
|
+
await waitFor(() => {
|
|
324
|
+
expect(canvas.getByText(/t with various annot/i)).toBeVisible()
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
// Verify reply input is present (readonly mode still allows viewing)
|
|
328
|
+
// Note: The actual readonly behavior depends on component implementation
|
|
329
|
+
// This test verifies the component renders in readonly mode
|
|
330
|
+
const replyInput = screen.queryByPlaceholderText("Reply...")
|
|
331
|
+
|
|
332
|
+
// In readonly mode, reply input should still be present but interactions are limited
|
|
333
|
+
// The key is that onAnnotationAdd should not be called for new comments
|
|
334
|
+
expect(args.onAnnotationAdd).not.toHaveBeenCalled()
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ============================================================================
|
|
339
|
+
// EDGE CASE TESTS (60% coverage required)
|
|
340
|
+
// ============================================================================
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Test: Empty reply submission prevented
|
|
344
|
+
* Verifies that empty replies cannot be submitted
|
|
345
|
+
*/
|
|
346
|
+
export const EmptyReplySubmissionPrevented: Story = {
|
|
347
|
+
args: {
|
|
348
|
+
content: sampleContent,
|
|
349
|
+
annotations: sampleAnnotations,
|
|
350
|
+
currentUser,
|
|
351
|
+
mode: 'review',
|
|
352
|
+
onAnnotationClick: fn(),
|
|
353
|
+
onAnnotationAdd: fn(),
|
|
354
|
+
onAnnotationUpdate: fn(),
|
|
355
|
+
},
|
|
356
|
+
play: async ({ canvasElement, args }) => {
|
|
357
|
+
const canvas = within(canvasElement)
|
|
358
|
+
|
|
359
|
+
// Wait for document to render
|
|
360
|
+
await waitFor(() => {
|
|
361
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
// Click annotation to open CommentBox
|
|
365
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
366
|
+
await userEvent.click(annotatedText)
|
|
367
|
+
|
|
368
|
+
// Wait for CommentBox and reply input
|
|
369
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
370
|
+
|
|
371
|
+
// Try to submit empty reply with Enter
|
|
372
|
+
await userEvent.click(replyInput)
|
|
373
|
+
await userEvent.keyboard('{Enter}')
|
|
374
|
+
|
|
375
|
+
// Verify onAnnotationUpdate was NOT called (empty submission prevented)
|
|
376
|
+
expect(args.onAnnotationUpdate).not.toHaveBeenCalled()
|
|
377
|
+
},
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Test: Whitespace-only reply prevented
|
|
382
|
+
* Verifies that replies with only whitespace cannot be submitted
|
|
383
|
+
*/
|
|
384
|
+
export const WhitespaceOnlyReplyPrevented: Story = {
|
|
385
|
+
args: {
|
|
386
|
+
content: sampleContent,
|
|
387
|
+
annotations: sampleAnnotations,
|
|
388
|
+
currentUser,
|
|
389
|
+
mode: 'review',
|
|
390
|
+
onAnnotationClick: fn(),
|
|
391
|
+
onAnnotationAdd: fn(),
|
|
392
|
+
onAnnotationUpdate: fn(),
|
|
393
|
+
},
|
|
394
|
+
play: async ({ canvasElement, args }) => {
|
|
395
|
+
const canvas = within(canvasElement)
|
|
396
|
+
|
|
397
|
+
// Wait for document to render
|
|
398
|
+
await waitFor(() => {
|
|
399
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
// Click annotation to open CommentBox
|
|
403
|
+
const annotatedText = canvas.getByText(/t with various annot/i)
|
|
404
|
+
await userEvent.click(annotatedText)
|
|
405
|
+
|
|
406
|
+
// Wait for CommentBox and reply input
|
|
407
|
+
const replyInput = await screen.findByPlaceholderText("Reply...")
|
|
408
|
+
|
|
409
|
+
// Type only whitespace
|
|
410
|
+
await userEvent.type(replyInput, ' ')
|
|
411
|
+
|
|
412
|
+
// Try to submit with Enter
|
|
413
|
+
await userEvent.keyboard('{Enter}')
|
|
414
|
+
|
|
415
|
+
// Verify onAnnotationUpdate was NOT called (whitespace-only prevented)
|
|
416
|
+
expect(args.onAnnotationUpdate).not.toHaveBeenCalled()
|
|
417
|
+
},
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Test: Multiple annotations render correctly
|
|
422
|
+
* Verifies that multiple annotations can coexist and be clicked independently
|
|
423
|
+
*/
|
|
424
|
+
export const MultipleAnnotationsRenderCorrectly: Story = {
|
|
425
|
+
args: {
|
|
426
|
+
content: sampleContent,
|
|
427
|
+
annotations: sampleAnnotations, // Contains both comment and suggestion
|
|
428
|
+
currentUser,
|
|
429
|
+
mode: 'review',
|
|
430
|
+
onAnnotationClick: fn(),
|
|
431
|
+
onAnnotationAdd: fn(),
|
|
432
|
+
onAnnotationUpdate: fn(),
|
|
433
|
+
},
|
|
434
|
+
play: async ({ canvasElement, args }) => {
|
|
435
|
+
const canvas = within(canvasElement)
|
|
436
|
+
|
|
437
|
+
// Wait for document to render
|
|
438
|
+
await waitFor(() => {
|
|
439
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeInTheDocument()
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
// Verify both annotations are present in the document
|
|
443
|
+
// First annotation: comment
|
|
444
|
+
expect(canvas.getByText(/t with various annot/i)).toBeInTheDocument()
|
|
445
|
+
|
|
446
|
+
// Second annotation: suggestion (check for the reason text or badge)
|
|
447
|
+
// Note: The exact text depends on how suggestions are rendered
|
|
448
|
+
// For now, just verify the document renders without errors
|
|
449
|
+
expect(canvas.getByText(/Document Review Example/i)).toBeVisible()
|
|
450
|
+
},
|
|
451
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock data for AIDocEditor stories and tests
|
|
3
|
+
*
|
|
4
|
+
* This file contains reusable mock data that can be imported by:
|
|
5
|
+
* - AIDocEditor.stories.tsx (regular stories)
|
|
6
|
+
* - AIDocEditor.behaviors.stories.tsx (behavior tests)
|
|
7
|
+
* - Any other test files that need AIDocEditor mock data
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { JSONContent } from '@tiptap/core'
|
|
11
|
+
import type { Annotation, User } from '@/types/ai-editor'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Sample document content for stories and tests
|
|
15
|
+
*/
|
|
16
|
+
export const sampleContent: JSONContent = {
|
|
17
|
+
type: 'doc',
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: 'heading',
|
|
21
|
+
attrs: { level: 1 },
|
|
22
|
+
content: [{ type: 'text', text: 'Document Review Example' }],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'paragraph',
|
|
26
|
+
content: [
|
|
27
|
+
{ type: 'text', text: 'This is a sample document with various annotations. ' },
|
|
28
|
+
{ type: 'text', text: 'Some text has comments, ' },
|
|
29
|
+
{ type: 'text', text: 'some has suggestions, ' },
|
|
30
|
+
{ type: 'text', text: 'and some has block additions.' },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'paragraph',
|
|
35
|
+
content: [
|
|
36
|
+
{ type: 'text', text: 'The editor supports inline annotations for comments and suggestions. ' },
|
|
37
|
+
{ type: 'text', text: 'Click on any highlighted text to see the annotation details.' },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Current user for stories and tests
|
|
45
|
+
*/
|
|
46
|
+
export const currentUser: User = {
|
|
47
|
+
id: 'user-1',
|
|
48
|
+
name: 'John Doe',
|
|
49
|
+
avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=John',
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Sample annotations for stories and tests
|
|
54
|
+
*/
|
|
55
|
+
export const sampleAnnotations: Annotation[] = [
|
|
56
|
+
{
|
|
57
|
+
type: 'comment',
|
|
58
|
+
id: 'comment-1',
|
|
59
|
+
range: { from: 50, to: 70 },
|
|
60
|
+
createdAt: Date.now() - 3600000,
|
|
61
|
+
userId: 'user-1',
|
|
62
|
+
data: {
|
|
63
|
+
thread: [
|
|
64
|
+
{
|
|
65
|
+
id: 'thread-1',
|
|
66
|
+
userId: 'user-1',
|
|
67
|
+
userName: 'John Doe',
|
|
68
|
+
avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=John',
|
|
69
|
+
contentRich: {
|
|
70
|
+
type: 'doc',
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: 'paragraph',
|
|
74
|
+
content: [{ type: 'text', text: 'This section needs clarification.' }],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
timestamp: Date.now() - 3600000,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: 'suggestion',
|
|
85
|
+
id: 'suggestion-1',
|
|
86
|
+
range: { from: 80, to: 100 },
|
|
87
|
+
createdAt: Date.now() - 1800000,
|
|
88
|
+
userId: 'ai-1',
|
|
89
|
+
data: {
|
|
90
|
+
action: 'delete',
|
|
91
|
+
oldText: 'some has suggestions',
|
|
92
|
+
reason: 'Remove redundant text',
|
|
93
|
+
thread: [],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
]
|