@docyrus/ui-pro-ai-assistant 0.0.1
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/dist/index.js +26161 -0
- package/dist/index.js.map +1 -0
- package/package.json +155 -0
- package/src/components/assistant-animations.tsx +29 -0
- package/src/components/assistant-dialogs.tsx +235 -0
- package/src/components/code-view.tsx +278 -0
- package/src/components/create-agent-task.tsx +104 -0
- package/src/components/create-new-work-version.tsx +30 -0
- package/src/components/extract-web.tsx +160 -0
- package/src/components/forward-to-agent.tsx +90 -0
- package/src/components/generate-chart.tsx +101 -0
- package/src/components/generative-action-button.tsx +122 -0
- package/src/components/generative-tool.tsx +685 -0
- package/src/components/generative-ui-object.tsx +210 -0
- package/src/components/input-area.tsx +1209 -0
- package/src/components/json-schema-layout.tsx +326 -0
- package/src/components/list-item-card.tsx +92 -0
- package/src/components/mermaid-diagram.tsx +192 -0
- package/src/components/preview-image.tsx +47 -0
- package/src/components/request-approval.tsx +48 -0
- package/src/components/request-user-input.tsx +270 -0
- package/src/components/search-web.tsx +319 -0
- package/src/components/sheet-command.tsx +88 -0
- package/src/components/shell-canvas.tsx +122 -0
- package/src/components/show-advanced-data-table.tsx +352 -0
- package/src/components/show-generated-content-options.tsx +93 -0
- package/src/components/show-people-cards.tsx +180 -0
- package/src/components/subagent-tool.tsx +180 -0
- package/src/components/text-editor-tool.tsx +328 -0
- package/src/components/work-canvas.tsx +88 -0
- package/src/components/work-card.tsx +42 -0
- package/src/declarations.d.ts +1 -0
- package/src/docy-assistant.tsx +1962 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/use-assistant-api.ts +507 -0
- package/src/hooks/use-deployment-data.ts +162 -0
- package/src/hooks/use-project-state.ts +347 -0
- package/src/hooks/use-session-state.ts +207 -0
- package/src/hooks/use-speech-recognition.ts +137 -0
- package/src/hooks/use-ui-state.ts +185 -0
- package/src/hooks/use-works-state.ts +146 -0
- package/src/i18n/context.tsx +253 -0
- package/src/i18n/index.ts +19 -0
- package/src/i18n/locales/de.json +198 -0
- package/src/i18n/locales/el.json +198 -0
- package/src/i18n/locales/en.json +226 -0
- package/src/i18n/locales/es.json +198 -0
- package/src/i18n/locales/fr.json +198 -0
- package/src/i18n/locales/it.json +198 -0
- package/src/i18n/locales/pt.json +198 -0
- package/src/i18n/locales/sl.json +198 -0
- package/src/i18n/locales/tr.json +211 -0
- package/src/i18n/types.ts +23 -0
- package/src/i18n/use-translation.ts +17 -0
- package/src/index.ts +18 -0
- package/src/internal/plate-editor/editor/auth-context.ts +11 -0
- package/src/internal/plate-editor/editor/editor-base-kit.tsx +39 -0
- package/src/internal/plate-editor/editor/editor-kit.tsx +89 -0
- package/src/internal/plate-editor/editor/plate-editor.tsx +75 -0
- package/src/internal/plate-editor/editor/plate-types.ts +126 -0
- package/src/internal/plate-editor/editor/plugins/ai-kit.tsx +172 -0
- package/src/internal/plate-editor/editor/plugins/autoformat-kit.tsx +211 -0
- package/src/internal/plate-editor/editor/plugins/basic-blocks-base-kit.tsx +26 -0
- package/src/internal/plate-editor/editor/plugins/basic-blocks-kit.tsx +51 -0
- package/src/internal/plate-editor/editor/plugins/basic-marks-base-kit.tsx +24 -0
- package/src/internal/plate-editor/editor/plugins/basic-marks-kit.tsx +38 -0
- package/src/internal/plate-editor/editor/plugins/basic-nodes-kit.tsx +6 -0
- package/src/internal/plate-editor/editor/plugins/block-menu-kit.tsx +14 -0
- package/src/internal/plate-editor/editor/plugins/block-placeholder-kit.tsx +17 -0
- package/src/internal/plate-editor/editor/plugins/block-selection-kit.tsx +31 -0
- package/src/internal/plate-editor/editor/plugins/callout-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/callout-kit.tsx +7 -0
- package/src/internal/plate-editor/editor/plugins/code-block-base-kit.tsx +23 -0
- package/src/internal/plate-editor/editor/plugins/code-block-kit.tsx +26 -0
- package/src/internal/plate-editor/editor/plugins/column-base-kit.tsx +8 -0
- package/src/internal/plate-editor/editor/plugins/column-kit.tsx +7 -0
- package/src/internal/plate-editor/editor/plugins/comment-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/comment-kit.tsx +174 -0
- package/src/internal/plate-editor/editor/plugins/copilot-kit.tsx +68 -0
- package/src/internal/plate-editor/editor/plugins/cursor-overlay-kit.tsx +13 -0
- package/src/internal/plate-editor/editor/plugins/date-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/date-kit.tsx +7 -0
- package/src/internal/plate-editor/editor/plugins/discussion-kit.tsx +36 -0
- package/src/internal/plate-editor/editor/plugins/dnd-kit.tsx +27 -0
- package/src/internal/plate-editor/editor/plugins/docx-export-kit.tsx +43 -0
- package/src/internal/plate-editor/editor/plugins/docx-kit.tsx +6 -0
- package/src/internal/plate-editor/editor/plugins/emoji-kit.tsx +15 -0
- package/src/internal/plate-editor/editor/plugins/exit-break-kit.tsx +12 -0
- package/src/internal/plate-editor/editor/plugins/floating-toolbar-kit.tsx +19 -0
- package/src/internal/plate-editor/editor/plugins/font-base-kit.tsx +36 -0
- package/src/internal/plate-editor/editor/plugins/font-kit.tsx +47 -0
- package/src/internal/plate-editor/editor/plugins/indent-base-kit.tsx +19 -0
- package/src/internal/plate-editor/editor/plugins/indent-kit.tsx +22 -0
- package/src/internal/plate-editor/editor/plugins/link-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/link-kit.tsx +35 -0
- package/src/internal/plate-editor/editor/plugins/list-base-kit.tsx +24 -0
- package/src/internal/plate-editor/editor/plugins/list-kit.tsx +27 -0
- package/src/internal/plate-editor/editor/plugins/markdown-kit.tsx +18 -0
- package/src/internal/plate-editor/editor/plugins/math-base-kit.tsx +8 -0
- package/src/internal/plate-editor/editor/plugins/math-kit.tsx +10 -0
- package/src/internal/plate-editor/editor/plugins/media-base-kit.tsx +37 -0
- package/src/internal/plate-editor/editor/plugins/media-kit.tsx +53 -0
- package/src/internal/plate-editor/editor/plugins/mention-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/mention-kit.tsx +36 -0
- package/src/internal/plate-editor/editor/plugins/slash-kit.tsx +17 -0
- package/src/internal/plate-editor/editor/plugins/suggestion-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/suggestion-kit.tsx +95 -0
- package/src/internal/plate-editor/editor/plugins/table-base-kit.tsx +20 -0
- package/src/internal/plate-editor/editor/plugins/table-kit.tsx +22 -0
- package/src/internal/plate-editor/editor/plugins/toc-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/toc-kit.tsx +14 -0
- package/src/internal/plate-editor/editor/plugins/toggle-base-kit.tsx +5 -0
- package/src/internal/plate-editor/editor/plugins/toggle-kit.tsx +9 -0
- package/src/internal/plate-editor/editor/transforms.ts +165 -0
- package/src/internal/plate-editor/editor/use-chat.ts +152 -0
- package/src/internal/plate-editor/hooks/index.ts +3 -0
- package/src/internal/plate-editor/hooks/use-copy-to-clipboard.ts +31 -0
- package/src/internal/plate-editor/hooks/use-is-touch-device.ts +26 -0
- package/src/internal/plate-editor/hooks/use-lock-scroll.ts +21 -0
- package/src/internal/plate-editor/hooks/use-media-query.ts +44 -0
- package/src/internal/plate-editor/hooks/use-mounted.ts +18 -0
- package/src/internal/plate-editor/hooks/use-on-click-outside.ts +114 -0
- package/src/internal/plate-editor/hooks/use-upload-file.ts +81 -0
- package/src/internal/plate-editor/i18n/context.tsx +58 -0
- package/src/internal/plate-editor/i18n/index.ts +3 -0
- package/src/internal/plate-editor/i18n/locales/de.json +57 -0
- package/src/internal/plate-editor/i18n/locales/el.json +57 -0
- package/src/internal/plate-editor/i18n/locales/en.json +57 -0
- package/src/internal/plate-editor/i18n/locales/es.json +57 -0
- package/src/internal/plate-editor/i18n/locales/fr.json +57 -0
- package/src/internal/plate-editor/i18n/locales/it.json +57 -0
- package/src/internal/plate-editor/i18n/locales/pt.json +57 -0
- package/src/internal/plate-editor/i18n/locales/sl.json +57 -0
- package/src/internal/plate-editor/i18n/locales/tr.json +57 -0
- package/src/internal/plate-editor/i18n/types.ts +59 -0
- package/src/internal/plate-editor/i18n/use-translation.ts +22 -0
- package/src/internal/plate-editor/index.ts +39 -0
- package/src/internal/plate-editor/lib/ai-output-converter.ts +153 -0
- package/src/internal/plate-editor/lib/download-file.ts +17 -0
- package/src/internal/plate-editor/plate-ui/ai-chat-editor.tsx +26 -0
- package/src/internal/plate-editor/plate-ui/ai-menu.tsx +828 -0
- package/src/internal/plate-editor/plate-ui/ai-node.tsx +41 -0
- package/src/internal/plate-editor/plate-ui/ai-toolbar-button.tsx +27 -0
- package/src/internal/plate-editor/plate-ui/alert-dialog.tsx +147 -0
- package/src/internal/plate-editor/plate-ui/align-toolbar-button.tsx +90 -0
- package/src/internal/plate-editor/plate-ui/avatar.tsx +3 -0
- package/src/internal/plate-editor/plate-ui/block-context-menu.tsx +106 -0
- package/src/internal/plate-editor/plate-ui/block-discussion.tsx +364 -0
- package/src/internal/plate-editor/plate-ui/block-draggable.tsx +556 -0
- package/src/internal/plate-editor/plate-ui/block-list-static.tsx +78 -0
- package/src/internal/plate-editor/plate-ui/block-list.tsx +85 -0
- package/src/internal/plate-editor/plate-ui/block-menu.tsx +557 -0
- package/src/internal/plate-editor/plate-ui/block-selection.tsx +47 -0
- package/src/internal/plate-editor/plate-ui/block-suggestion.tsx +469 -0
- package/src/internal/plate-editor/plate-ui/blockquote-node-static.tsx +10 -0
- package/src/internal/plate-editor/plate-ui/blockquote-node.tsx +11 -0
- package/src/internal/plate-editor/plate-ui/button.tsx +190 -0
- package/src/internal/plate-editor/plate-ui/calendar.tsx +3 -0
- package/src/internal/plate-editor/plate-ui/callout-node-static.tsx +76 -0
- package/src/internal/plate-editor/plate-ui/callout-node.tsx +54 -0
- package/src/internal/plate-editor/plate-ui/caption.tsx +48 -0
- package/src/internal/plate-editor/plate-ui/checkbox.tsx +3 -0
- package/src/internal/plate-editor/plate-ui/code-block-node-static.tsx +172 -0
- package/src/internal/plate-editor/plate-ui/code-block-node.tsx +228 -0
- package/src/internal/plate-editor/plate-ui/code-node-static.tsx +11 -0
- package/src/internal/plate-editor/plate-ui/code-node.tsx +12 -0
- package/src/internal/plate-editor/plate-ui/column-node-static.tsx +65 -0
- package/src/internal/plate-editor/plate-ui/column-node.tsx +24 -0
- package/src/internal/plate-editor/plate-ui/command.tsx +204 -0
- package/src/internal/plate-editor/plate-ui/comment-node-static.tsx +12 -0
- package/src/internal/plate-editor/plate-ui/comment-node.tsx +45 -0
- package/src/internal/plate-editor/plate-ui/comment-toolbar-button.tsx +24 -0
- package/src/internal/plate-editor/plate-ui/comment.tsx +619 -0
- package/src/internal/plate-editor/plate-ui/cursor-overlay.tsx +85 -0
- package/src/internal/plate-editor/plate-ui/date-node-static.tsx +43 -0
- package/src/internal/plate-editor/plate-ui/date-node.tsx +56 -0
- package/src/internal/plate-editor/plate-ui/dialog.tsx +426 -0
- package/src/internal/plate-editor/plate-ui/dropdown-menu.tsx +266 -0
- package/src/internal/plate-editor/plate-ui/editor-static.tsx +40 -0
- package/src/internal/plate-editor/plate-ui/editor.tsx +148 -0
- package/src/internal/plate-editor/plate-ui/emoji-node.tsx +48 -0
- package/src/internal/plate-editor/plate-ui/emoji-toolbar-button.tsx +626 -0
- package/src/internal/plate-editor/plate-ui/equation-node-static.tsx +155 -0
- package/src/internal/plate-editor/plate-ui/equation-node.tsx +226 -0
- package/src/internal/plate-editor/plate-ui/equation-toolbar-button.tsx +26 -0
- package/src/internal/plate-editor/plate-ui/export-toolbar-button.tsx +208 -0
- package/src/internal/plate-editor/plate-ui/fixed-toolbar-buttons.tsx +157 -0
- package/src/internal/plate-editor/plate-ui/fixed-toolbar.tsx +27 -0
- package/src/internal/plate-editor/plate-ui/floating-discussion.tsx +1129 -0
- package/src/internal/plate-editor/plate-ui/floating-toolbar-buttons.tsx +129 -0
- package/src/internal/plate-editor/plate-ui/floating-toolbar.tsx +99 -0
- package/src/internal/plate-editor/plate-ui/font-color-toolbar-button.tsx +211 -0
- package/src/internal/plate-editor/plate-ui/font-size-toolbar-button.tsx +154 -0
- package/src/internal/plate-editor/plate-ui/ghost-text.tsx +20 -0
- package/src/internal/plate-editor/plate-ui/heading-node-static.tsx +52 -0
- package/src/internal/plate-editor/plate-ui/heading-node.tsx +56 -0
- package/src/internal/plate-editor/plate-ui/highlight-node-static.tsx +9 -0
- package/src/internal/plate-editor/plate-ui/highlight-node.tsx +11 -0
- package/src/internal/plate-editor/plate-ui/history-toolbar-button.tsx +52 -0
- package/src/internal/plate-editor/plate-ui/hover-card.tsx +7 -0
- package/src/internal/plate-editor/plate-ui/hr-node-static.tsx +18 -0
- package/src/internal/plate-editor/plate-ui/hr-node.tsx +28 -0
- package/src/internal/plate-editor/plate-ui/import-toolbar-button.tsx +124 -0
- package/src/internal/plate-editor/plate-ui/indent-toolbar-button.tsx +34 -0
- package/src/internal/plate-editor/plate-ui/inline-combobox.tsx +409 -0
- package/src/internal/plate-editor/plate-ui/input.tsx +39 -0
- package/src/internal/plate-editor/plate-ui/insert-toolbar-button.tsx +260 -0
- package/src/internal/plate-editor/plate-ui/label.tsx +1 -0
- package/src/internal/plate-editor/plate-ui/line-height-toolbar-button.tsx +71 -0
- package/src/internal/plate-editor/plate-ui/link-node-static.tsx +15 -0
- package/src/internal/plate-editor/plate-ui/link-node.tsx +33 -0
- package/src/internal/plate-editor/plate-ui/link-toolbar-button.tsx +30 -0
- package/src/internal/plate-editor/plate-ui/link-toolbar.tsx +149 -0
- package/src/internal/plate-editor/plate-ui/list-toolbar-button.tsx +179 -0
- package/src/internal/plate-editor/plate-ui/mark-toolbar-button.tsx +36 -0
- package/src/internal/plate-editor/plate-ui/media-audio-node-static.tsx +21 -0
- package/src/internal/plate-editor/plate-ui/media-audio-node.tsx +32 -0
- package/src/internal/plate-editor/plate-ui/media-embed-node.tsx +103 -0
- package/src/internal/plate-editor/plate-ui/media-file-node-static.tsx +30 -0
- package/src/internal/plate-editor/plate-ui/media-file-node.tsx +52 -0
- package/src/internal/plate-editor/plate-ui/media-image-node-static.tsx +37 -0
- package/src/internal/plate-editor/plate-ui/media-image-node.tsx +183 -0
- package/src/internal/plate-editor/plate-ui/media-placeholder-node.tsx +441 -0
- package/src/internal/plate-editor/plate-ui/media-preview-dialog.tsx +127 -0
- package/src/internal/plate-editor/plate-ui/media-toolbar-button.tsx +229 -0
- package/src/internal/plate-editor/plate-ui/media-toolbar.tsx +216 -0
- package/src/internal/plate-editor/plate-ui/media-upload-toast.tsx +73 -0
- package/src/internal/plate-editor/plate-ui/media-video-node-static.tsx +35 -0
- package/src/internal/plate-editor/plate-ui/media-video-node.tsx +119 -0
- package/src/internal/plate-editor/plate-ui/mention-node-static.tsx +46 -0
- package/src/internal/plate-editor/plate-ui/mention-node.tsx +79 -0
- package/src/internal/plate-editor/plate-ui/menu.tsx +532 -0
- package/src/internal/plate-editor/plate-ui/mode-toolbar-button.tsx +126 -0
- package/src/internal/plate-editor/plate-ui/more-toolbar-button.tsx +34 -0
- package/src/internal/plate-editor/plate-ui/paragraph-node-static.tsx +15 -0
- package/src/internal/plate-editor/plate-ui/paragraph-node.tsx +16 -0
- package/src/internal/plate-editor/plate-ui/popover.tsx +77 -0
- package/src/internal/plate-editor/plate-ui/progress.tsx +1 -0
- package/src/internal/plate-editor/plate-ui/remote-cursor-overlay.tsx +81 -0
- package/src/internal/plate-editor/plate-ui/resize-handle.tsx +88 -0
- package/src/internal/plate-editor/plate-ui/separator.tsx +43 -0
- package/src/internal/plate-editor/plate-ui/slash-node.tsx +435 -0
- package/src/internal/plate-editor/plate-ui/spinner.tsx +1 -0
- package/src/internal/plate-editor/plate-ui/suggestion-node-static.tsx +35 -0
- package/src/internal/plate-editor/plate-ui/suggestion-node.tsx +168 -0
- package/src/internal/plate-editor/plate-ui/suggestion-toolbar-button.tsx +24 -0
- package/src/internal/plate-editor/plate-ui/table-node-static.tsx +85 -0
- package/src/internal/plate-editor/plate-ui/table-node.tsx +285 -0
- package/src/internal/plate-editor/plate-ui/table-toolbar-button.tsx +254 -0
- package/src/internal/plate-editor/plate-ui/tabs.tsx +3 -0
- package/src/internal/plate-editor/plate-ui/textarea.tsx +58 -0
- package/src/internal/plate-editor/plate-ui/toc-node-static.tsx +142 -0
- package/src/internal/plate-editor/plate-ui/toc-node.tsx +57 -0
- package/src/internal/plate-editor/plate-ui/toc-sidebar.tsx +50 -0
- package/src/internal/plate-editor/plate-ui/toggle-node-static.tsx +18 -0
- package/src/internal/plate-editor/plate-ui/toggle-node.tsx +33 -0
- package/src/internal/plate-editor/plate-ui/toggle-toolbar-button.tsx +26 -0
- package/src/internal/plate-editor/plate-ui/toggle.tsx +3 -0
- package/src/internal/plate-editor/plate-ui/toolbar.tsx +380 -0
- package/src/internal/plate-editor/plate-ui/tooltip.tsx +149 -0
- package/src/internal/plate-editor/plate-ui/turn-into-toolbar-button.tsx +177 -0
- package/src/internal/plate-editor/types/index.ts +22 -0
- package/src/internal/plate-editor/vite.ts +284 -0
- package/src/internal/sheets/components/univer-sheets.tsx +1104 -0
- package/src/internal/sheets/i18n/context.tsx +183 -0
- package/src/internal/sheets/i18n/index.ts +19 -0
- package/src/internal/sheets/i18n/locales/de.json +21 -0
- package/src/internal/sheets/i18n/locales/el.json +21 -0
- package/src/internal/sheets/i18n/locales/en.json +21 -0
- package/src/internal/sheets/i18n/locales/es.json +21 -0
- package/src/internal/sheets/i18n/locales/fr.json +21 -0
- package/src/internal/sheets/i18n/locales/it.json +21 -0
- package/src/internal/sheets/i18n/locales/pt.json +21 -0
- package/src/internal/sheets/i18n/locales/sl.json +21 -0
- package/src/internal/sheets/i18n/locales/tr.json +21 -0
- package/src/internal/sheets/i18n/types.ts +23 -0
- package/src/internal/sheets/i18n/use-translation.ts +17 -0
- package/src/internal/sheets/index.ts +14 -0
- package/src/internal/sheets/types/css.d.ts +11 -0
- package/src/internal/sheets/types/index.ts +260 -0
- package/src/internal/sheets/xlsx.ts +1169 -0
- package/src/lib/api-client.ts +77 -0
- package/src/lib/assistant-api-actions.ts +549 -0
- package/src/lib/assistant-config.tsx +71 -0
- package/src/lib/class-utils.ts +40 -0
- package/src/lib/index.ts +7 -0
- package/src/lib/message-utils.ts +131 -0
- package/src/tools/tools-schema.json +512 -0
- package/src/types/index.ts +235 -0
- package/src/views/assistant-view.tsx +1137 -0
- package/src/views/canvas-app.tsx +839 -0
- package/src/views/canvas-code.tsx +93 -0
- package/src/views/canvas-deep-research.tsx +44 -0
- package/src/views/canvas-image.tsx +25 -0
- package/src/views/canvas-record-view.tsx +285 -0
- package/src/views/canvas-spreadsheet.tsx +125 -0
- package/src/views/canvas-text.tsx +52 -0
- package/src/views/canvas.tsx +274 -0
- package/src/views/chat-panel.tsx +149 -0
- package/src/views/index.ts +20 -0
- package/src/views/memories-panel.tsx +365 -0
- package/src/views/message-list.tsx +370 -0
- package/src/views/project-detail.tsx +257 -0
- package/src/views/projects-panel.tsx +131 -0
- package/src/views/sessions-list.tsx +98 -0
- package/src/views/sidebar-content.tsx +256 -0
- package/src/views/work-detail.tsx +98 -0
- package/src/vite.ts +284 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AlertTriangle,
|
|
5
|
+
CalendarClock,
|
|
6
|
+
Check,
|
|
7
|
+
Loader2
|
|
8
|
+
} from 'lucide-react';
|
|
9
|
+
|
|
10
|
+
import { cn } from '@docyrus/ui-pro-shared/lib/utils';
|
|
11
|
+
|
|
12
|
+
interface CreateAgentTaskProps {
|
|
13
|
+
taskPrompt?: string;
|
|
14
|
+
taskDescription?: string;
|
|
15
|
+
scheduleType?: string;
|
|
16
|
+
state: string;
|
|
17
|
+
output?: any;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function truncateText(text: string, maxLength: number): string {
|
|
21
|
+
if (!text) return '';
|
|
22
|
+
|
|
23
|
+
return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function CreateAgentTask({
|
|
27
|
+
taskPrompt,
|
|
28
|
+
taskDescription,
|
|
29
|
+
scheduleType,
|
|
30
|
+
state,
|
|
31
|
+
output
|
|
32
|
+
}: CreateAgentTaskProps) {
|
|
33
|
+
const isSuccess = output?.status === 'success' || output?.result?.success;
|
|
34
|
+
const outputMessage: string | null = output ? (output.text || output.result?.message || null) : null;
|
|
35
|
+
|
|
36
|
+
const statusConfig = (() => {
|
|
37
|
+
if (state === 'output-available') {
|
|
38
|
+
if (isSuccess) {
|
|
39
|
+
return {
|
|
40
|
+
label: 'Created',
|
|
41
|
+
bgColor: 'bg-emerald-100',
|
|
42
|
+
textColor: 'text-emerald-700',
|
|
43
|
+
Icon: Check,
|
|
44
|
+
animate: false
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
label: 'Failed',
|
|
50
|
+
bgColor: 'bg-rose-100',
|
|
51
|
+
textColor: 'text-rose-700',
|
|
52
|
+
Icon: AlertTriangle,
|
|
53
|
+
animate: false
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
label: 'Creating...',
|
|
59
|
+
bgColor: 'bg-sky-100',
|
|
60
|
+
textColor: 'text-sky-700',
|
|
61
|
+
Icon: Loader2,
|
|
62
|
+
animate: true
|
|
63
|
+
};
|
|
64
|
+
})();
|
|
65
|
+
|
|
66
|
+
const {
|
|
67
|
+
label, bgColor, textColor, Icon, animate
|
|
68
|
+
} = statusConfig;
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div className="rounded-lg border border-slate-200 bg-white p-4 hover:border-slate-300 transition-colors max-w-md">
|
|
72
|
+
<div className="flex items-start justify-between gap-4">
|
|
73
|
+
<div className="flex-grow min-w-0">
|
|
74
|
+
<div className="flex items-center gap-2 mb-1.5">
|
|
75
|
+
<span className={cn('inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium', bgColor, textColor)}>
|
|
76
|
+
<Icon className={cn('h-3 w-3', animate && 'animate-spin')} />
|
|
77
|
+
{label}
|
|
78
|
+
</span>
|
|
79
|
+
{scheduleType === 'scheduled' && (
|
|
80
|
+
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-violet-100 text-violet-700">
|
|
81
|
+
<CalendarClock className="h-3 w-3" />
|
|
82
|
+
Scheduled
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<h3 className="font-medium text-slate-800 mb-1">
|
|
88
|
+
{taskDescription || truncateText(taskPrompt ?? '', 60)}
|
|
89
|
+
</h3>
|
|
90
|
+
|
|
91
|
+
{taskDescription && taskPrompt && (
|
|
92
|
+
<p className="text-sm text-slate-500 mb-2 line-clamp-2">{taskPrompt}</p>
|
|
93
|
+
)}
|
|
94
|
+
|
|
95
|
+
{outputMessage && state === 'output-available' && (
|
|
96
|
+
<div className={cn('mt-2 text-xs rounded-md px-3 py-2', isSuccess ? 'bg-emerald-50 text-emerald-700' : 'bg-rose-50 text-rose-700')}>
|
|
97
|
+
{outputMessage}
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { FilePlus, Loader2 } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
interface CreateNewWorkVersionProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
state?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function CreateNewWorkVersion({ title, description, state }: CreateNewWorkVersionProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className="flex flex-row items-center space-x-4">
|
|
14
|
+
<div className="rounded-lg shadow-sm w-fit min-w-64 border bg-card p-3 flex items-center space-x-3">
|
|
15
|
+
<div className="flex-none p-2 bg-slate-50 rounded">
|
|
16
|
+
<FilePlus className="size-5" />
|
|
17
|
+
</div>
|
|
18
|
+
<div className="grow min-w-0">
|
|
19
|
+
<div className="font-medium text-sm truncate">{title || 'New Version'}</div>
|
|
20
|
+
{description && (
|
|
21
|
+
<p className="text-xs text-muted-foreground truncate">{description}</p>
|
|
22
|
+
)}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
{state === 'input-streaming' && (
|
|
26
|
+
<Loader2 className="size-5 animate-spin text-primary" />
|
|
27
|
+
)}
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { CheckCircle, Globe, Loader2 } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { Card } from '@docyrus/ui-pro-shared/components/card';
|
|
8
|
+
|
|
9
|
+
import { useApiClient } from '../lib/api-client';
|
|
10
|
+
|
|
11
|
+
interface ExtractWebProps {
|
|
12
|
+
title?: string;
|
|
13
|
+
status?: string;
|
|
14
|
+
state?: string;
|
|
15
|
+
runId?: string;
|
|
16
|
+
onOpen?: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TERMINAL_STATUSES = [
|
|
20
|
+
'completed',
|
|
21
|
+
'failed',
|
|
22
|
+
'error',
|
|
23
|
+
'success'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export function ExtractWeb({
|
|
27
|
+
title,
|
|
28
|
+
status: initialStatus,
|
|
29
|
+
state,
|
|
30
|
+
runId,
|
|
31
|
+
onOpen
|
|
32
|
+
}: ExtractWebProps) {
|
|
33
|
+
const [currentStatus, setCurrentStatus] = useState(initialStatus || '');
|
|
34
|
+
const [pollingFailed, setPollingFailed] = useState(false);
|
|
35
|
+
const apiClient = useApiClient();
|
|
36
|
+
const isPollingRef = useRef(false);
|
|
37
|
+
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
38
|
+
const unmountedRef = useRef(false);
|
|
39
|
+
const currentStatusRef = useRef(initialStatus || '');
|
|
40
|
+
|
|
41
|
+
const capitalizedStatus = currentStatus ? currentStatus.charAt(0).toUpperCase() + currentStatus.slice(1) : 'Processing';
|
|
42
|
+
|
|
43
|
+
const isCompleted = currentStatus === 'completed' || currentStatus === 'success';
|
|
44
|
+
const isSpinning = !isCompleted && !pollingFailed;
|
|
45
|
+
|
|
46
|
+
const handleClick = () => {
|
|
47
|
+
if (state === 'output-available') {
|
|
48
|
+
onOpen?.();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const stopPolling = () => {
|
|
53
|
+
isPollingRef.current = false;
|
|
54
|
+
if (timeoutRef.current) {
|
|
55
|
+
clearTimeout(timeoutRef.current);
|
|
56
|
+
timeoutRef.current = null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const poll = async () => {
|
|
61
|
+
if (!runId || isPollingRef.current || unmountedRef.current) return;
|
|
62
|
+
if (TERMINAL_STATUSES.includes(currentStatusRef.current)) return;
|
|
63
|
+
|
|
64
|
+
isPollingRef.current = true;
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const data = await apiClient.get(`ai/external-task-jobs/${runId}/check`);
|
|
68
|
+
|
|
69
|
+
if (unmountedRef.current) return;
|
|
70
|
+
|
|
71
|
+
const responseData = (data.data as any) || data;
|
|
72
|
+
const status = responseData?.status as string | undefined;
|
|
73
|
+
|
|
74
|
+
if (status) {
|
|
75
|
+
currentStatusRef.current = status;
|
|
76
|
+
setCurrentStatus(status);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
isPollingRef.current = false;
|
|
80
|
+
|
|
81
|
+
if (!status || TERMINAL_STATUSES.includes(status)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
timeoutRef.current = setTimeout(() => {
|
|
86
|
+
void poll();
|
|
87
|
+
}, 20000);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (!unmountedRef.current) {
|
|
90
|
+
console.error('ExtractWeb: polling error, stopping:', error);
|
|
91
|
+
setPollingFailed(true);
|
|
92
|
+
}
|
|
93
|
+
isPollingRef.current = false;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
const status = initialStatus || '';
|
|
99
|
+
|
|
100
|
+
currentStatusRef.current = status;
|
|
101
|
+
setCurrentStatus(status);
|
|
102
|
+
|
|
103
|
+
if (TERMINAL_STATUSES.includes(status)) {
|
|
104
|
+
stopPolling();
|
|
105
|
+
}
|
|
106
|
+
}, [initialStatus]);
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
unmountedRef.current = false;
|
|
110
|
+
setPollingFailed(false);
|
|
111
|
+
|
|
112
|
+
if (runId && !TERMINAL_STATUSES.includes(currentStatusRef.current)) {
|
|
113
|
+
void poll();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return () => {
|
|
117
|
+
unmountedRef.current = true;
|
|
118
|
+
stopPolling();
|
|
119
|
+
};
|
|
120
|
+
// poll uses refs internally, safe to omit
|
|
121
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
122
|
+
}, [runId]);
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div className="flex flex-row items-center space-x-4">
|
|
126
|
+
<Card
|
|
127
|
+
className="p-4 w-fit min-w-96 max-w-96 shadow-sm flex flex-col space-y-2 cursor-pointer hover:bg-accent/50 transition-colors"
|
|
128
|
+
onClick={handleClick}>
|
|
129
|
+
<div className="flex items-start space-x-2">
|
|
130
|
+
<div className="flex-none p-2 bg-slate-50 rounded">
|
|
131
|
+
<Globe className="size-8 text-muted-foreground" />
|
|
132
|
+
</div>
|
|
133
|
+
<div className="grow space-y-1 min-w-0">
|
|
134
|
+
<div className="font-medium text-base truncate">{title || 'Web Extraction'}</div>
|
|
135
|
+
{isCompleted ? (
|
|
136
|
+
<div className="flex items-center gap-2">
|
|
137
|
+
<span className="inline-flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-700">
|
|
138
|
+
<CheckCircle className="size-3" />
|
|
139
|
+
{capitalizedStatus}
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
) : (
|
|
143
|
+
<div>
|
|
144
|
+
<span className="inline-flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-700">
|
|
145
|
+
{isSpinning && <Loader2 className="size-3 animate-spin" />}
|
|
146
|
+
{capitalizedStatus}{isSpinning ? '...' : ''}
|
|
147
|
+
</span>
|
|
148
|
+
{isSpinning && (
|
|
149
|
+
<p className="text-sm text-muted-foreground mt-1">
|
|
150
|
+
This process may take some time. You will receive a notification once it is complete.
|
|
151
|
+
</p>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</Card>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { ArrowRight } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { Button } from '@docyrus/ui-pro-shared/components/button';
|
|
8
|
+
|
|
9
|
+
import { useApiClient } from '../lib/api-client';
|
|
10
|
+
|
|
11
|
+
interface ForwardToAgentProps {
|
|
12
|
+
agentId?: string;
|
|
13
|
+
prompt?: string;
|
|
14
|
+
state?: string;
|
|
15
|
+
onForward?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function ForwardToAgent({ agentId, onForward }: ForwardToAgentProps) {
|
|
19
|
+
const apiClient = useApiClient();
|
|
20
|
+
const [agentName, setAgentName] = useState('');
|
|
21
|
+
const [avatar, setAvatar] = useState('');
|
|
22
|
+
const [loading, setLoading] = useState(false);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!agentId) {
|
|
26
|
+
setAgentName('');
|
|
27
|
+
setAvatar('');
|
|
28
|
+
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const fetchAgent = async () => {
|
|
33
|
+
setLoading(true);
|
|
34
|
+
try {
|
|
35
|
+
const response = await apiClient.get(`/ai/agents/${agentId}`);
|
|
36
|
+
|
|
37
|
+
if (response.success && response.data) {
|
|
38
|
+
const data = response.data as { name?: string; avatar?: { signed_url?: string } | string };
|
|
39
|
+
|
|
40
|
+
setAgentName(data.name || '');
|
|
41
|
+
const avatarUrl = typeof data.avatar === 'string' ? data.avatar : data.avatar?.signed_url || '';
|
|
42
|
+
|
|
43
|
+
setAvatar(avatarUrl);
|
|
44
|
+
}
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.error('[ForwardToAgent] Error fetching agent:', err);
|
|
47
|
+
} finally {
|
|
48
|
+
setLoading(false);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
fetchAgent();
|
|
53
|
+
}, [agentId, apiClient]);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className="p-4 m-2 border bg-white border-slate-200 max-w-[500px] rounded-lg animate-bounce-subtle">
|
|
57
|
+
<div className="flex items-center gap-2">
|
|
58
|
+
<ArrowRight className="size-5 text-blue-500 flex-shrink-0" />
|
|
59
|
+
<span className="text-sm font-medium text-slate-700 whitespace-nowrap">
|
|
60
|
+
Forwarding to agent
|
|
61
|
+
</span>
|
|
62
|
+
{(avatar || agentName) && (
|
|
63
|
+
<div className="flex items-center gap-1.5 ml-1">
|
|
64
|
+
{avatar && (
|
|
65
|
+
<img
|
|
66
|
+
src={avatar}
|
|
67
|
+
alt="Agent Avatar"
|
|
68
|
+
className="w-5 h-5 rounded-full object-cover" />
|
|
69
|
+
)}
|
|
70
|
+
{agentName && (
|
|
71
|
+
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-700">
|
|
72
|
+
{agentName}
|
|
73
|
+
</span>
|
|
74
|
+
)}
|
|
75
|
+
</div>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
78
|
+
<div className="mt-3 flex justify-end">
|
|
79
|
+
<Button
|
|
80
|
+
size="sm"
|
|
81
|
+
disabled={loading}
|
|
82
|
+
onClick={onForward}
|
|
83
|
+
className="gap-1.5 bg-emerald-600 hover:bg-emerald-700 text-white">
|
|
84
|
+
<ArrowRight className="size-3.5" />
|
|
85
|
+
{agentName ? `Forward to ${agentName}` : 'Forward to agent'}
|
|
86
|
+
</Button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { ChevronDown } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@docyrus/ui-pro-shared/lib/utils';
|
|
8
|
+
|
|
9
|
+
interface GenerateChartProps {
|
|
10
|
+
spec?: Record<string, any>;
|
|
11
|
+
time?: Record<string, any>;
|
|
12
|
+
state?: string;
|
|
13
|
+
errorText?: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function GenerateChart({
|
|
20
|
+
spec, state, errorText, title = 'Chart', description, className
|
|
21
|
+
}: GenerateChartProps) {
|
|
22
|
+
const [open, setOpen] = useState(true);
|
|
23
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
24
|
+
const chartRef = useRef<any>(null);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (state !== 'output-available' || !spec || !open || !containerRef.current) return;
|
|
28
|
+
|
|
29
|
+
let isMounted = true;
|
|
30
|
+
|
|
31
|
+
const initChart = async () => {
|
|
32
|
+
try {
|
|
33
|
+
const { default: VChart } = await import('@visactor/vchart');
|
|
34
|
+
|
|
35
|
+
if (!isMounted || !containerRef.current) return;
|
|
36
|
+
|
|
37
|
+
if (chartRef.current) {
|
|
38
|
+
chartRef.current.updateSpecSync(spec);
|
|
39
|
+
chartRef.current.renderSync();
|
|
40
|
+
} else {
|
|
41
|
+
const chart = new VChart(spec as any, { dom: containerRef.current });
|
|
42
|
+
|
|
43
|
+
chart.renderSync();
|
|
44
|
+
chartRef.current = chart;
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error('Failed to render chart:', error);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
initChart();
|
|
52
|
+
|
|
53
|
+
return () => {
|
|
54
|
+
isMounted = false;
|
|
55
|
+
};
|
|
56
|
+
}, [spec, state, open]);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
return () => {
|
|
60
|
+
if (chartRef.current) {
|
|
61
|
+
chartRef.current.release();
|
|
62
|
+
chartRef.current = null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="rounded-xl shadow bg-card border overflow-hidden">
|
|
69
|
+
{/* Header */}
|
|
70
|
+
<div
|
|
71
|
+
role="button"
|
|
72
|
+
tabIndex={0}
|
|
73
|
+
onClick={() => setOpen(v => !v)}
|
|
74
|
+
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && setOpen(v => !v)}
|
|
75
|
+
className="flex w-full items-center justify-between gap-1.5 px-4 py-3 text-left bg-muted/50 hover:bg-muted transition-colors cursor-pointer select-none">
|
|
76
|
+
<div className="flex items-center gap-2 grow min-w-0">
|
|
77
|
+
<span className="font-medium text-sm truncate">{title}</span>
|
|
78
|
+
{description && (
|
|
79
|
+
<span className="text-xs text-muted-foreground truncate hidden sm:block">{description}</span>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
<ChevronDown className={cn('size-4 text-muted-foreground transition-transform shrink-0', open && 'rotate-180')} />
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
{/* Body — always in DOM so VChart container keeps its ref */}
|
|
86
|
+
<div className={cn('p-4', !open && 'hidden', className)}>
|
|
87
|
+
{state !== 'output-available' && !errorText && (
|
|
88
|
+
<div className="w-full h-[300px] rounded-lg bg-muted/30 animate-pulse" />
|
|
89
|
+
)}
|
|
90
|
+
{errorText && (
|
|
91
|
+
<div className="text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-lg p-3">
|
|
92
|
+
{errorText}
|
|
93
|
+
</div>
|
|
94
|
+
)}
|
|
95
|
+
<div
|
|
96
|
+
ref={containerRef}
|
|
97
|
+
className="w-full min-h-[300px]" />
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type ElementType } from 'react';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Eye, HelpCircle, Pencil, PlusCircle
|
|
7
|
+
} from 'lucide-react';
|
|
8
|
+
|
|
9
|
+
import { resolveToolIcon } from '@docyrus/ui-pro-shared/ai';
|
|
10
|
+
import { Button } from '@docyrus/ui-pro-shared/components/button';
|
|
11
|
+
import { cn } from '@docyrus/ui-pro-shared/lib/utils';
|
|
12
|
+
|
|
13
|
+
type Action = 'showCreateRecordForm' | 'showUpdateRecordForm' | 'showRecordDetailsForm';
|
|
14
|
+
|
|
15
|
+
interface GenerativeActionButtonProps {
|
|
16
|
+
action: Action | string;
|
|
17
|
+
data?: Record<string, any>;
|
|
18
|
+
title?: string;
|
|
19
|
+
icon?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
onAction?: (action: string, data?: Record<string, any>) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ACTION_CONFIG: Record<Action, { label: string; FallbackIcon: ElementType }> = {
|
|
25
|
+
showCreateRecordForm: { label: 'Create Record', FallbackIcon: PlusCircle },
|
|
26
|
+
showUpdateRecordForm: { label: 'Update Record', FallbackIcon: Pencil },
|
|
27
|
+
showRecordDetailsForm: { label: 'View Record', FallbackIcon: Eye }
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function getComputedTitle(data?: Record<string, any>): string {
|
|
31
|
+
if (!data?.defaultValues) return '';
|
|
32
|
+
|
|
33
|
+
const values = typeof data.defaultValues === 'string' ? (() => {
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(data.defaultValues);
|
|
36
|
+
} catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
})() : data.defaultValues;
|
|
40
|
+
|
|
41
|
+
if (Array.isArray(values)) {
|
|
42
|
+
return values.length > 1 ? `${values.length} items` : 'Untitled Record';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (values as Record<string, any>)?.name
|
|
46
|
+
?? (values as Record<string, any>)?.title
|
|
47
|
+
?? 'Untitled Record';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getDescription(data?: Record<string, any>): string | null {
|
|
51
|
+
if (!data?.defaultValues || Array.isArray(data.defaultValues)) return null;
|
|
52
|
+
|
|
53
|
+
const values = typeof data.defaultValues === 'string' ? (() => {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(data.defaultValues);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
})() : data.defaultValues;
|
|
60
|
+
|
|
61
|
+
return (values as Record<string, any>)?.description ?? null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function GenerativeActionButton({
|
|
65
|
+
action,
|
|
66
|
+
data,
|
|
67
|
+
title,
|
|
68
|
+
icon,
|
|
69
|
+
className,
|
|
70
|
+
onAction
|
|
71
|
+
}: GenerativeActionButtonProps) {
|
|
72
|
+
const config = ACTION_CONFIG[action as Action] ?? { label: 'Action', FallbackIcon: HelpCircle };
|
|
73
|
+
const { label, FallbackIcon } = config;
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
* Use the icon string from the tool output (e.g. "huge form") if available,
|
|
77
|
+
* otherwise fall back to the action-specific icon.
|
|
78
|
+
*/
|
|
79
|
+
const resolvedIcon = icon ? resolveToolIcon(icon) : <FallbackIcon className="size-6 text-muted-foreground" />;
|
|
80
|
+
|
|
81
|
+
const buttonIcon = icon ? resolveToolIcon(icon) : <FallbackIcon className="size-3.5" />;
|
|
82
|
+
|
|
83
|
+
const displayTitle = title || getComputedTitle(data);
|
|
84
|
+
const description = getDescription(data);
|
|
85
|
+
|
|
86
|
+
const handleClick = () => {
|
|
87
|
+
onAction?.(action, data);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div
|
|
92
|
+
className={cn(
|
|
93
|
+
'flex flex-col space-y-3 rounded-lg shadow-sm hover:shadow-md w-fit min-w-80 max-w-96 border p-4',
|
|
94
|
+
className
|
|
95
|
+
)}>
|
|
96
|
+
<div
|
|
97
|
+
role="button"
|
|
98
|
+
tabIndex={0}
|
|
99
|
+
onClick={handleClick}
|
|
100
|
+
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && handleClick()}
|
|
101
|
+
className="flex items-start gap-3 cursor-pointer rounded-lg">
|
|
102
|
+
<div className="shrink-0 p-2 bg-muted rounded [&_svg]:size-6 [&_svg]:text-muted-foreground">
|
|
103
|
+
{resolvedIcon}
|
|
104
|
+
</div>
|
|
105
|
+
<div className="grow space-y-1 min-w-0">
|
|
106
|
+
{displayTitle && (
|
|
107
|
+
<div className="font-medium text-base truncate">{displayTitle}</div>
|
|
108
|
+
)}
|
|
109
|
+
{description && (
|
|
110
|
+
<div className="text-sm text-muted-foreground line-clamp-2">{description}</div>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div className="flex items-center justify-end">
|
|
115
|
+
<Button size="sm" onClick={handleClick} className="gap-1.5 [&_svg]:size-3.5">
|
|
116
|
+
{buttonIcon}
|
|
117
|
+
{label}
|
|
118
|
+
</Button>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|