@vertesia/ui 1.5.0-dev.20260807.073259Z → 1.5.0-dev.20260826.064249Z
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 +1 -7
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -1
- package/lib/core/components/shadcn/filters/filter/dateFilter.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filter/dateFilter.js +1 -1
- package/lib/core/components/shadcn/filters/filter/dateFilter.js.map +1 -1
- package/lib/core/components/shadcn/filters/filters.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filters.js +1 -1
- package/lib/core/components/shadcn/filters/filters.js.map +1 -1
- package/lib/core/components/shadcn/index.d.ts +1 -0
- package/lib/core/components/shadcn/index.d.ts.map +1 -1
- package/lib/core/components/shadcn/index.js +1 -0
- package/lib/core/components/shadcn/index.js.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.js +1 -3
- package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
- package/lib/core/components/shadcn/overflowTabs.d.ts +59 -0
- package/lib/core/components/shadcn/overflowTabs.d.ts.map +1 -0
- package/lib/core/components/shadcn/overflowTabs.js +173 -0
- package/lib/core/components/shadcn/overflowTabs.js.map +1 -0
- package/lib/core/components/shadcn/selectBox.js +2 -2
- package/lib/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/core/components/shadcn/theme/ThemeProvider.d.ts +3 -1
- package/lib/core/components/shadcn/theme/ThemeProvider.d.ts.map +1 -1
- package/lib/core/components/shadcn/theme/ThemeProvider.js +8 -9
- package/lib/core/components/shadcn/theme/ThemeProvider.js.map +1 -1
- package/lib/core/utils/dayjs.d.ts +12 -0
- package/lib/core/utils/dayjs.d.ts.map +1 -0
- package/lib/core/utils/dayjs.js +16 -0
- package/lib/core/utils/dayjs.js.map +1 -0
- package/lib/env/index.d.ts +17 -0
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js +18 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts +1 -0
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/PayloadBuilder.js +22 -5
- package/lib/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.js +3 -135
- package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +19 -4
- package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +6 -0
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +99 -29
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +10 -9
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +5 -8
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +45 -4
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +3 -3
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +9 -121
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +6 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js +19 -11
- package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/features/agent/chat/VegaLiteChart.d.ts.map +1 -1
- package/lib/features/agent/chat/VegaLiteChart.js +11 -3
- package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +3 -0
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/document-viewer/UniversalDocumentViewer.d.ts.map +1 -1
- package/lib/features/document-viewer/UniversalDocumentViewer.js +1 -1
- package/lib/features/document-viewer/UniversalDocumentViewer.js.map +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts +14 -2
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.js +20 -2
- package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.d.ts +3 -3
- package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.js +6 -1
- package/lib/features/facets/CollectionsFacetsNav.js.map +1 -1
- package/lib/features/facets/DocumentsFacetsNav.d.ts +3 -3
- package/lib/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/DocumentsFacetsNav.js +20 -8
- package/lib/features/facets/DocumentsFacetsNav.js.map +1 -1
- package/lib/features/facets/InteractionsFacetsNav.d.ts +3 -3
- package/lib/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/InteractionsFacetsNav.js +11 -1
- package/lib/features/facets/InteractionsFacetsNav.js.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts +3 -3
- package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.js +6 -1
- package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
- package/lib/features/facets/RunsFacetsNav.d.ts +4 -14
- package/lib/features/facets/RunsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/RunsFacetsNav.js +26 -15
- package/lib/features/facets/RunsFacetsNav.js.map +1 -1
- package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts +4 -3
- package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/WorkflowExecutionsFacetsNav.js +18 -10
- package/lib/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -1
- package/lib/features/facets/index.d.ts +1 -1
- package/lib/features/facets/index.d.ts.map +1 -1
- package/lib/features/facets/index.js.map +1 -1
- package/lib/features/facets/utils/SearchInterface.d.ts +4 -3
- package/lib/features/facets/utils/SearchInterface.d.ts.map +1 -1
- package/lib/features/facets/utils/SearchInterface.js +4 -0
- package/lib/features/facets/utils/SearchInterface.js.map +1 -1
- package/lib/features/layout/GenericPageNavHeader.d.ts +8 -1
- package/lib/features/layout/GenericPageNavHeader.d.ts.map +1 -1
- package/lib/features/layout/GenericPageNavHeader.js +9 -1
- package/lib/features/layout/GenericPageNavHeader.js.map +1 -1
- package/lib/features/magic-pdf/DownloadPopover.d.ts +3 -2
- package/lib/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
- package/lib/features/magic-pdf/DownloadPopover.js.map +1 -1
- package/lib/features/magic-pdf/GroundedExtractionView.d.ts.map +1 -1
- package/lib/features/magic-pdf/GroundedExtractionView.js +51 -64
- package/lib/features/magic-pdf/GroundedExtractionView.js.map +1 -1
- package/lib/features/oauth/McpConnectionsButton.d.ts +1 -1
- package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -1
- package/lib/features/oauth/McpConnectionsButton.js +2 -2
- package/lib/features/oauth/McpConnectionsButton.js.map +1 -1
- package/lib/features/oauth/McpConnectionsDialog.d.ts +1 -1
- package/lib/features/oauth/McpConnectionsDialog.js +2 -2
- package/lib/features/oauth/McpConnectionsDialog.js.map +1 -1
- package/lib/features/oauth/useMcpConnections.d.ts +4 -5
- package/lib/features/oauth/useMcpConnections.d.ts.map +1 -1
- package/lib/features/oauth/useMcpConnections.js +20 -4
- package/lib/features/oauth/useMcpConnections.js.map +1 -1
- package/lib/features/pdf-viewer/PdfPageRenderer.d.ts.map +1 -1
- package/lib/features/pdf-viewer/PdfPageRenderer.js +9 -11
- package/lib/features/pdf-viewer/PdfPageRenderer.js.map +1 -1
- package/lib/features/pdf-viewer/lazyReactPdf.d.ts +10 -0
- package/lib/features/pdf-viewer/lazyReactPdf.d.ts.map +1 -0
- package/lib/features/pdf-viewer/lazyReactPdf.js +25 -0
- package/lib/features/pdf-viewer/lazyReactPdf.js.map +1 -0
- package/lib/features/store/collections/CollectionsTable.d.ts.map +1 -1
- package/lib/features/store/collections/CollectionsTable.js +1 -3
- package/lib/features/store/collections/CollectionsTable.js.map +1 -1
- package/lib/features/store/collections/EditCollectionView.js +1 -1
- package/lib/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/features/store/objects/ExportPropertiesModal.d.ts +3 -1
- package/lib/features/store/objects/ExportPropertiesModal.d.ts.map +1 -1
- package/lib/features/store/objects/ExportPropertiesModal.js +5 -5
- package/lib/features/store/objects/ExportPropertiesModal.js.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +4 -10
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.js +8 -3
- package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
- package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/features/store/objects/layout/renderers.js +1 -5
- package/lib/features/store/objects/layout/renderers.js.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts +29 -62
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.js +2 -0
- package/lib/features/store/objects/search/DocumentSearchContext.js.map +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.d.ts +6 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js +4 -3
- package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
- package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js +2 -2
- package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
- package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
- package/lib/features/store/types/ContentObjectTypesTable.js +1 -3
- package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.js +11 -1
- package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
- package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
- package/lib/features/store/types/ObjectSchemaEditor.js +6 -2
- package/lib/features/store/types/ObjectSchemaEditor.js.map +1 -1
- package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
- package/lib/features/store/types/TableLayoutEditor.js +2 -0
- package/lib/features/store/types/TableLayoutEditor.js.map +1 -1
- package/lib/features/store/types/TypeRegistry.d.ts +272 -0
- package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +271 -0
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
- package/lib/features/user/UserInfo.d.ts.map +1 -1
- package/lib/features/user/UserInfo.js +2 -4
- package/lib/features/user/UserInfo.js.map +1 -1
- package/lib/features/views/ViewActions.d.ts +32 -0
- package/lib/features/views/ViewActions.d.ts.map +1 -0
- package/lib/features/views/ViewActions.js +186 -0
- package/lib/features/views/ViewActions.js.map +1 -0
- package/lib/features/views/ViewDropTarget.d.ts +15 -0
- package/lib/features/views/ViewDropTarget.d.ts.map +1 -0
- package/lib/features/views/ViewDropTarget.js +79 -0
- package/lib/features/views/ViewDropTarget.js.map +1 -0
- package/lib/features/views/ViewExperience.d.ts +3 -2
- package/lib/features/views/ViewExperience.d.ts.map +1 -1
- package/lib/features/views/ViewExperience.js +103 -12
- package/lib/features/views/ViewExperience.js.map +1 -1
- package/lib/features/views/ViewNavigation.d.ts +1 -1
- package/lib/features/views/ViewNavigation.d.ts.map +1 -1
- package/lib/features/views/ViewNavigation.js +14 -5
- package/lib/features/views/ViewNavigation.js.map +1 -1
- package/lib/features/views/ViewResults.d.ts +1 -1
- package/lib/features/views/ViewResults.d.ts.map +1 -1
- package/lib/features/views/ViewResults.js +124 -34
- package/lib/features/views/ViewResults.js.map +1 -1
- package/lib/features/views/index.d.ts +1 -0
- package/lib/features/views/index.d.ts.map +1 -1
- package/lib/features/views/index.js +1 -0
- package/lib/features/views/index.js.map +1 -1
- package/lib/features/views/types.d.ts +46 -1
- package/lib/features/views/types.d.ts.map +1 -1
- package/lib/features/views/viewState.d.ts.map +1 -1
- package/lib/features/views/viewState.js +34 -0
- package/lib/features/views/viewState.js.map +1 -1
- package/lib/i18n/LanguageProvider.d.ts +3 -1
- package/lib/i18n/LanguageProvider.d.ts.map +1 -1
- package/lib/i18n/LanguageProvider.js +9 -7
- package/lib/i18n/LanguageProvider.js.map +1 -1
- package/lib/i18n/instance.d.ts +2 -0
- package/lib/i18n/instance.d.ts.map +1 -1
- package/lib/i18n/instance.js +45 -26
- package/lib/i18n/instance.js.map +1 -1
- package/lib/i18n/locales/ar.json +261 -15
- package/lib/i18n/locales/de.json +259 -13
- package/lib/i18n/locales/en.json +30 -4
- package/lib/i18n/locales/es.json +260 -14
- package/lib/i18n/locales/fr.json +259 -13
- package/lib/i18n/locales/it.json +259 -13
- package/lib/i18n/locales/ja.json +257 -10
- package/lib/i18n/locales/ko.json +257 -10
- package/lib/i18n/locales/pt.json +259 -13
- package/lib/i18n/locales/ru.json +256 -10
- package/lib/i18n/locales/tr.json +256 -10
- package/lib/i18n/locales/zh-TW.json +257 -10
- package/lib/i18n/locales/zh.json +257 -10
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +8 -16
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +25 -19
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/session/auth/firebase.js +1 -1
- package/lib/session/auth/firebase.js.map +1 -1
- package/lib/shell/VertesiaShell.d.ts.map +1 -1
- package/lib/shell/VertesiaShell.js +2 -1
- package/lib/shell/VertesiaShell.js.map +1 -1
- package/lib/shell/apps/AppInstallationProvider.d.ts +4 -2
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/apps/IframeAppContextSync.d.ts +3 -0
- package/lib/shell/apps/IframeAppContextSync.d.ts.map +1 -0
- package/lib/shell/apps/IframeAppContextSync.js +95 -0
- package/lib/shell/apps/IframeAppContextSync.js.map +1 -0
- package/lib/shell/apps/iframe-auth.d.ts +55 -0
- package/lib/shell/apps/iframe-auth.d.ts.map +1 -0
- package/lib/shell/apps/iframe-auth.js +154 -0
- package/lib/shell/apps/iframe-auth.js.map +1 -0
- package/lib/shell/apps/index.d.ts +2 -0
- package/lib/shell/apps/index.d.ts.map +1 -1
- package/lib/shell/apps/index.js +2 -0
- package/lib/shell/apps/index.js.map +1 -1
- package/lib/vertesia-ui-core.js +4 -4
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-env.js +1 -1
- package/lib/vertesia-ui-env.js.map +1 -1
- package/lib/vertesia-ui-features.js +32 -34
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +16 -16
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +4 -4
- package/lib/vertesia-ui-rich-text.js.map +1 -1
- package/lib/vertesia-ui-router.js +1 -1
- package/lib/vertesia-ui-router.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +20 -20
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.js +43 -2
- package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
- package/lib/widgets/markdown/MermaidDiagram.d.ts.map +1 -1
- package/lib/widgets/markdown/MermaidDiagram.js +35 -22
- package/lib/widgets/markdown/MermaidDiagram.js.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.js +14 -10
- package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
- package/package.json +24 -29
- package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +1 -1
- package/src/core/components/shadcn/filters/filter/dateFilter.tsx +1 -1
- package/src/core/components/shadcn/filters/filters.tsx +1 -1
- package/src/core/components/shadcn/index.ts +1 -0
- package/src/core/components/shadcn/modal/dialog.test.tsx +35 -0
- package/src/core/components/shadcn/modal/dialog.tsx +0 -4
- package/src/core/components/shadcn/overflowTabs.tsx +320 -0
- package/src/core/components/shadcn/selectBox.tsx +2 -2
- package/src/core/components/shadcn/theme/ThemeProvider.tsx +10 -9
- package/src/core/utils/dayjs.ts +17 -0
- package/src/css/base.css +78 -0
- package/src/env/index.test.ts +94 -0
- package/src/env/index.ts +36 -1
- package/src/features/agent/PayloadBuilder.test.ts +68 -0
- package/src/features/agent/PayloadBuilder.tsx +28 -4
- package/src/features/agent/chat/AgentRightPanel.tsx +2 -252
- package/src/features/agent/chat/ArtifactsTab.tsx +1 -0
- package/src/features/agent/chat/AskUserWidget.test.tsx +20 -1
- package/src/features/agent/chat/AskUserWidget.tsx +22 -6
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +160 -0
- package/src/features/agent/chat/ModernAgentConversation.tsx +111 -31
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +86 -67
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +90 -7
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +4 -6
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +103 -1
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +50 -4
- package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +18 -1
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +37 -167
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +94 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +19 -10
- package/src/features/agent/chat/VegaLiteChart.tsx +32 -14
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +18 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +3 -0
- package/src/features/document-viewer/UniversalDocumentViewer.tsx +1 -1
- package/src/features/facets/AgentRunnerFacetsNav.tsx +44 -4
- package/src/features/facets/CollectionsFacetsNav.tsx +15 -4
- package/src/features/facets/DocumentsFacetsNav.tsx +25 -8
- package/src/features/facets/FacetQueryHandlers.test.ts +84 -0
- package/src/features/facets/InteractionsFacetsNav.tsx +20 -4
- package/src/features/facets/PromptsFacetsNav.tsx +15 -4
- package/src/features/facets/RunsFacetsNav.test.ts +59 -0
- package/src/features/facets/RunsFacetsNav.tsx +40 -30
- package/src/features/facets/WorkflowExecutionsFacetsNav.test.ts +57 -0
- package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +36 -16
- package/src/features/facets/index.ts +1 -0
- package/src/features/facets/utils/SearchInterface.tsx +12 -3
- package/src/features/layout/GenericPageNavHeader.tsx +16 -0
- package/src/features/magic-pdf/DownloadPopover.tsx +1 -2
- package/src/features/magic-pdf/GroundedExtractionView.test.tsx +7 -1
- package/src/features/magic-pdf/GroundedExtractionView.tsx +162 -242
- package/src/features/oauth/McpConnectionsButton.test.tsx +18 -1
- package/src/features/oauth/McpConnectionsButton.tsx +6 -2
- package/src/features/oauth/McpConnectionsDialog.tsx +3 -3
- package/src/features/oauth/useMcpConnections.test.ts +1 -0
- package/src/features/oauth/useMcpConnections.ts +24 -7
- package/src/features/pdf-viewer/PdfPageRenderer.tsx +76 -71
- package/src/features/pdf-viewer/lazyReactPdf.ts +33 -0
- package/src/features/store/collections/CollectionsTable.tsx +1 -4
- package/src/features/store/collections/EditCollectionView.tsx +1 -1
- package/src/features/store/objects/ExportPropertiesModal.tsx +25 -16
- package/src/features/store/objects/components/ContentOverview.tsx +2 -28
- package/src/features/store/objects/components/TextEditorPanel.tsx +13 -3
- package/src/features/store/objects/layout/renderers.tsx +1 -6
- package/src/features/store/objects/search/DocumentSearchContext.ts +4 -2
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +10 -3
- package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +15 -6
- package/src/features/store/types/ContentObjectTypesTable.tsx +1 -4
- package/src/features/store/types/IntakePolicyEditor.tsx +11 -1
- package/src/features/store/types/ObjectSchemaEditor.tsx +6 -2
- package/src/features/store/types/TableLayoutEditor.tsx +2 -0
- package/src/features/user/UserInfo.test.tsx +10 -0
- package/src/features/user/UserInfo.tsx +2 -7
- package/src/features/views/ViewActions.test.tsx +80 -0
- package/src/features/views/ViewActions.tsx +352 -0
- package/src/features/views/ViewDropTarget.test.tsx +150 -0
- package/src/features/views/ViewDropTarget.tsx +140 -0
- package/src/features/views/ViewExperience.test.tsx +72 -0
- package/src/features/views/ViewExperience.tsx +189 -22
- package/src/features/views/ViewMedia.test.tsx +180 -0
- package/src/features/views/ViewNavigation.test.tsx +42 -0
- package/src/features/views/ViewNavigation.tsx +43 -5
- package/src/features/views/ViewResults.tsx +243 -26
- package/src/features/views/index.ts +1 -0
- package/src/features/views/types.ts +50 -0
- package/src/features/views/viewState.test.ts +7 -1
- package/src/features/views/viewState.ts +32 -0
- package/src/i18n/LanguageProvider.tsx +15 -8
- package/src/i18n/instance.test.ts +30 -0
- package/src/i18n/instance.ts +67 -40
- package/src/i18n/locales/ar.json +1157 -911
- package/src/i18n/locales/de.json +1113 -867
- package/src/i18n/locales/en.json +30 -4
- package/src/i18n/locales/es.json +1124 -878
- package/src/i18n/locales/fr.json +1124 -878
- package/src/i18n/locales/it.json +1124 -878
- package/src/i18n/locales/ja.json +1113 -866
- package/src/i18n/locales/ko.json +1113 -866
- package/src/i18n/locales/pt.json +1124 -878
- package/src/i18n/locales/ru.json +1135 -889
- package/src/i18n/locales/tr.json +1113 -867
- package/src/i18n/locales/zh-TW.json +1113 -866
- package/src/i18n/locales/zh.json +1113 -866
- package/src/i18n/rtl.test.ts +16 -7
- package/src/rich-text/VertesiaRichTextEditor.test.tsx +33 -1
- package/src/session/UserSessionProvider.tsx +8 -20
- package/src/session/auth/composable.scope.test.ts +1 -1
- package/src/session/auth/composable.test.ts +61 -1
- package/src/session/auth/composable.ts +29 -23
- package/src/session/auth/firebase.ts +1 -1
- package/src/shell/VertesiaShell.tsx +2 -0
- package/src/shell/apps/IframeAppContextSync.test.tsx +196 -0
- package/src/shell/apps/IframeAppContextSync.tsx +101 -0
- package/src/shell/apps/iframe-auth.test.ts +118 -0
- package/src/shell/apps/iframe-auth.ts +193 -0
- package/src/shell/apps/index.ts +2 -0
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +12 -3
- package/src/widgets/markdown/MarkdownRenderer.tsx +50 -2
- package/src/widgets/markdown/MermaidDiagram.tsx +38 -22
- package/src/widgets/monacoEditor/MonacoEditor.tsx +27 -20
- package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts +0 -25
- package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts.map +0 -1
- package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js +0 -42
- package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js.map +0 -1
- package/src/features/magic-pdf/GroundedExtractionAssistantPanel.tsx +0 -86
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { VertesiaClient } from '@vertesia/client';
|
|
2
|
+
import type { InCodeInteraction, JSONSchema } from '@vertesia/common';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { PayloadBuilderStore } from './PayloadBuilder';
|
|
5
|
+
|
|
6
|
+
describe('PayloadBuilder', () => {
|
|
7
|
+
it('accepts a resolved interaction with no prompt segments', () => {
|
|
8
|
+
const store = new PayloadBuilderStore({} as VertesiaClient);
|
|
9
|
+
const interaction: InCodeInteraction = {
|
|
10
|
+
type: 'sys',
|
|
11
|
+
id: 'sys:GeneralAgent',
|
|
12
|
+
name: 'GeneralAgent',
|
|
13
|
+
tags: ['agent', 'general-purpose'],
|
|
14
|
+
title: 'General Agent',
|
|
15
|
+
description: 'A general-purpose agent.',
|
|
16
|
+
agent_runner_options: {
|
|
17
|
+
is_agent: true,
|
|
18
|
+
request_template: '{{user_prompt}}',
|
|
19
|
+
},
|
|
20
|
+
prompts: [],
|
|
21
|
+
};
|
|
22
|
+
const listener = vi.fn();
|
|
23
|
+
store.subscribe(listener);
|
|
24
|
+
|
|
25
|
+
store.snapshot.setInteraction(interaction);
|
|
26
|
+
|
|
27
|
+
expect(store.snapshot.interaction).toMatchObject(interaction);
|
|
28
|
+
expect(store.snapshot.interactionParamsSchema).toBeNull();
|
|
29
|
+
expect(listener).toHaveBeenCalled();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('updates draft prompt data without notifying every builder consumer', () => {
|
|
33
|
+
const store = new PayloadBuilderStore({} as VertesiaClient);
|
|
34
|
+
const listener = vi.fn();
|
|
35
|
+
store.subscribe(listener);
|
|
36
|
+
|
|
37
|
+
store.snapshot.setDraftData({ task: 'Write a summary' });
|
|
38
|
+
|
|
39
|
+
expect(store.snapshot.data).toEqual({ task: 'Write a summary' });
|
|
40
|
+
expect(listener).not.toHaveBeenCalled();
|
|
41
|
+
|
|
42
|
+
store.snapshot.setModel('model-id');
|
|
43
|
+
|
|
44
|
+
expect(listener).toHaveBeenCalledOnce();
|
|
45
|
+
expect(store.snapshot.data).toEqual({ task: 'Write a summary' });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('validates the latest draft prompt data without requiring a published snapshot', () => {
|
|
49
|
+
const store = new PayloadBuilderStore({} as VertesiaClient);
|
|
50
|
+
const consoleWarn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
51
|
+
const schema: JSONSchema = {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
task: { type: 'string', minLength: 1, format: 'textarea' },
|
|
55
|
+
},
|
|
56
|
+
required: ['task'],
|
|
57
|
+
};
|
|
58
|
+
store.snapshot.interactionParamsSchema = schema;
|
|
59
|
+
|
|
60
|
+
store.snapshot.setDraftData({});
|
|
61
|
+
expect(store.snapshot.validateInput().isValid).toBe(false);
|
|
62
|
+
|
|
63
|
+
store.snapshot.setDraftData({ task: 'Write a summary' });
|
|
64
|
+
expect(store.snapshot.validateInput()).toEqual({ isValid: true });
|
|
65
|
+
expect(consoleWarn).not.toHaveBeenCalled();
|
|
66
|
+
consoleWarn.mockRestore();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type InCodeInteraction,
|
|
7
7
|
type JSONSchema,
|
|
8
8
|
mergeInCodePromptSchemas,
|
|
9
|
+
SupportedProviders,
|
|
9
10
|
supportsToolUse,
|
|
10
11
|
type UserChannel,
|
|
11
12
|
type WorkflowInteractionVars,
|
|
@@ -16,9 +17,27 @@ import Ajv, { type ValidateFunction } from 'ajv';
|
|
|
16
17
|
import type React from 'react';
|
|
17
18
|
import { createContext, useContext, useState, useSyncExternalStore } from 'react';
|
|
18
19
|
|
|
20
|
+
// Interaction schemas also use `format` as a UI editor hint (for example, `textarea`
|
|
21
|
+
// and `media`). Those values are not validation formats, so do not make AJV inspect them.
|
|
22
|
+
// Reusing one instance also avoids rebuilding AJV's compiler on the Start button click.
|
|
23
|
+
const inputSchemaAjv = new Ajv({ strict: false, validateFormats: false });
|
|
24
|
+
|
|
19
25
|
export type WorkflowMode = 'start' | 'schedule';
|
|
20
26
|
type ModelOptions = NonNullable<WorkflowInteractionVars['config']['model_options']>;
|
|
21
27
|
|
|
28
|
+
type ModelProvider = Parameters<typeof supportsToolUse>[1];
|
|
29
|
+
|
|
30
|
+
function getExecutableProvider(provider: ExecutionEnvironmentRef['provider']): ModelProvider | undefined {
|
|
31
|
+
if (
|
|
32
|
+
provider === SupportedProviders.virtual_lb ||
|
|
33
|
+
provider === SupportedProviders.virtual_mediator ||
|
|
34
|
+
provider === SupportedProviders.test
|
|
35
|
+
) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return provider as ModelProvider;
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
export interface ScheduledWorkflowConfig {
|
|
23
42
|
name: string;
|
|
24
43
|
description?: string;
|
|
@@ -323,13 +342,14 @@ export class PayloadBuilder {
|
|
|
323
342
|
if (environment?.id !== this._environment?.id) {
|
|
324
343
|
this._environment = environment;
|
|
325
344
|
if (!this._preserveRunValues) {
|
|
345
|
+
const provider = environment ? getExecutableProvider(environment.provider) : undefined;
|
|
326
346
|
// First try to use the interaction model, then the environment default model
|
|
327
347
|
const interactionModel = this.interaction?.runtime?.model;
|
|
328
|
-
if (interactionModel &&
|
|
348
|
+
if (interactionModel && provider && supportsToolUse(interactionModel, provider)) {
|
|
329
349
|
this._model = interactionModel;
|
|
330
350
|
} else {
|
|
331
351
|
this._model =
|
|
332
|
-
environment?.default_model && supportsToolUse(environment.default_model,
|
|
352
|
+
environment?.default_model && provider && supportsToolUse(environment.default_model, provider)
|
|
333
353
|
? environment.default_model
|
|
334
354
|
: '';
|
|
335
355
|
}
|
|
@@ -435,6 +455,11 @@ export class PayloadBuilder {
|
|
|
435
455
|
setData(data: JSONObject) {
|
|
436
456
|
this.data = data;
|
|
437
457
|
}
|
|
458
|
+
setDraftData(data: JSONObject) {
|
|
459
|
+
// Generated form controls manage their own live input state. Publishing an external-store
|
|
460
|
+
// update here would rerender every PayloadBuilder consumer for each keystroke.
|
|
461
|
+
this._data = data;
|
|
462
|
+
}
|
|
438
463
|
setPreserveRunValues(value: boolean) {
|
|
439
464
|
this.preserveRunValues = value;
|
|
440
465
|
}
|
|
@@ -530,9 +555,8 @@ export class PayloadBuilder {
|
|
|
530
555
|
|
|
531
556
|
// If schema has changed or validator not initialized, recompile
|
|
532
557
|
if (!this._inputValidator || this._inputValidator.schema !== this._interactionParamsSchema) {
|
|
533
|
-
const ajv = new Ajv({ strict: false });
|
|
534
558
|
this._inputValidator = {
|
|
535
|
-
validate:
|
|
559
|
+
validate: inputSchemaAjv.compile(this._interactionParamsSchema),
|
|
536
560
|
schema: this._interactionParamsSchema,
|
|
537
561
|
};
|
|
538
562
|
}
|
|
@@ -5,10 +5,7 @@ import {
|
|
|
5
5
|
Button,
|
|
6
6
|
Center,
|
|
7
7
|
cn,
|
|
8
|
-
|
|
9
|
-
DropdownMenuContent,
|
|
10
|
-
DropdownMenuItem,
|
|
11
|
-
DropdownMenuTrigger,
|
|
8
|
+
OverflowTabsBar,
|
|
12
9
|
type Tab as TabDefinition,
|
|
13
10
|
Tabs,
|
|
14
11
|
TabsPanel,
|
|
@@ -18,7 +15,6 @@ import { useUITranslation } from '@vertesia/ui/i18n';
|
|
|
18
15
|
import { useUserSession } from '@vertesia/ui/session';
|
|
19
16
|
import {
|
|
20
17
|
CheckCircleIcon,
|
|
21
|
-
ChevronDownIcon,
|
|
22
18
|
ClipboardCopyIcon,
|
|
23
19
|
DownloadCloudIcon,
|
|
24
20
|
FileTextIcon,
|
|
@@ -27,7 +23,7 @@ import {
|
|
|
27
23
|
XCircleIcon,
|
|
28
24
|
XIcon,
|
|
29
25
|
} from 'lucide-react';
|
|
30
|
-
import React, { useCallback,
|
|
26
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
31
27
|
import { ArtifactsTab } from './ArtifactsTab.js';
|
|
32
28
|
import { BrowserUseWidget, getLatestBrowserUseByWorkstream } from './BrowserUseWidget.js';
|
|
33
29
|
import { DocumentPanel } from './DocumentPanel.js';
|
|
@@ -347,252 +343,6 @@ function WorkstreamsTab({ workstreams, messages, runId }: WorkstreamsTabProps) {
|
|
|
347
343
|
);
|
|
348
344
|
}
|
|
349
345
|
|
|
350
|
-
// ---------------------------------------------------------------------------
|
|
351
|
-
// Overflow tab bar
|
|
352
|
-
// ---------------------------------------------------------------------------
|
|
353
|
-
|
|
354
|
-
// Tab-item styling, matching core's TabsTrigger underline tabs.
|
|
355
|
-
const TAB_ITEM_BASE =
|
|
356
|
-
'flex items-center border-b-2 px-2 py-1.5 text-sm font-medium whitespace-nowrap cursor-pointer shrink-0';
|
|
357
|
-
const TAB_ITEM_INACTIVE = 'border-transparent text-muted-foreground hover:border-border hover:text-foreground';
|
|
358
|
-
const TAB_ITEM_ACTIVE = 'border-primary text-primary';
|
|
359
|
-
const TAB_GAP_PX = 4; // matches the `gap-1` between tab items
|
|
360
|
-
|
|
361
|
-
interface OverflowMoreMenuProps {
|
|
362
|
-
/** The overflowed tabs to list inside the menu. */
|
|
363
|
-
tabs: TabDefinition[];
|
|
364
|
-
current: string;
|
|
365
|
-
onTabChange: (name: string) => void;
|
|
366
|
-
label: string;
|
|
367
|
-
/** Whether the active tab is one of the overflowed tabs. */
|
|
368
|
-
active: boolean;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/** Trailing "More" dropdown of overflowed tabs; opens on hover, click, or keyboard. */
|
|
372
|
-
function OverflowMoreMenu({ tabs, current, onTabChange, label, active }: OverflowMoreMenuProps) {
|
|
373
|
-
const [open, setOpen] = useState(false);
|
|
374
|
-
const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
375
|
-
const openedByHover = useRef(false);
|
|
376
|
-
|
|
377
|
-
const cancelClose = () => {
|
|
378
|
-
if (closeTimer.current) {
|
|
379
|
-
clearTimeout(closeTimer.current);
|
|
380
|
-
closeTimer.current = null;
|
|
381
|
-
}
|
|
382
|
-
};
|
|
383
|
-
const openOnHover = () => {
|
|
384
|
-
cancelClose();
|
|
385
|
-
openedByHover.current = true;
|
|
386
|
-
setOpen(true);
|
|
387
|
-
};
|
|
388
|
-
// Delay the close so the pointer can travel across the gap onto the menu.
|
|
389
|
-
const closeAfterDelay = () => {
|
|
390
|
-
cancelClose();
|
|
391
|
-
closeTimer.current = setTimeout(() => setOpen(false), 150);
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
// Clear any pending close timer on unmount.
|
|
395
|
-
useEffect(() => () => clearTimeout(closeTimer.current ?? undefined), []);
|
|
396
|
-
|
|
397
|
-
return (
|
|
398
|
-
// Non-modal: a modal menu sets body `pointer-events: none` while open, which makes
|
|
399
|
-
// the hover open/close flap. It still closes on outside-click / Escape.
|
|
400
|
-
<DropdownMenu
|
|
401
|
-
modal={false}
|
|
402
|
-
open={open}
|
|
403
|
-
onOpenChange={(next) => {
|
|
404
|
-
// Fired by click / keyboard / dismiss (not by hover); keep our state in sync.
|
|
405
|
-
cancelClose();
|
|
406
|
-
if (next) openedByHover.current = false;
|
|
407
|
-
setOpen(next);
|
|
408
|
-
}}
|
|
409
|
-
>
|
|
410
|
-
<DropdownMenuTrigger asChild>
|
|
411
|
-
{/* Tab-bar primitive: raw button is the menu trigger (asChild). */}
|
|
412
|
-
<button
|
|
413
|
-
type="button"
|
|
414
|
-
onMouseEnter={openOnHover}
|
|
415
|
-
onMouseLeave={closeAfterDelay}
|
|
416
|
-
className={cn(TAB_ITEM_BASE, active ? TAB_ITEM_ACTIVE : TAB_ITEM_INACTIVE)}
|
|
417
|
-
>
|
|
418
|
-
{label}
|
|
419
|
-
<ChevronDownIcon className="ms-1 size-4" />
|
|
420
|
-
</button>
|
|
421
|
-
</DropdownMenuTrigger>
|
|
422
|
-
<DropdownMenuContent
|
|
423
|
-
align="end"
|
|
424
|
-
className="w-max"
|
|
425
|
-
onMouseEnter={cancelClose}
|
|
426
|
-
onMouseLeave={closeAfterDelay}
|
|
427
|
-
onCloseAutoFocus={(e) => {
|
|
428
|
-
// Keep hover-opens from returning the focus ring to the trigger.
|
|
429
|
-
if (openedByHover.current) e.preventDefault();
|
|
430
|
-
}}
|
|
431
|
-
>
|
|
432
|
-
{tabs.map((tab) => (
|
|
433
|
-
<DropdownMenuItem
|
|
434
|
-
key={tab.name}
|
|
435
|
-
disabled={tab.disabled}
|
|
436
|
-
onClick={() => onTabChange(tab.name)}
|
|
437
|
-
className={cn(tab.name === current && 'text-primary')}
|
|
438
|
-
>
|
|
439
|
-
{tab.label}
|
|
440
|
-
</DropdownMenuItem>
|
|
441
|
-
))}
|
|
442
|
-
</DropdownMenuContent>
|
|
443
|
-
</DropdownMenu>
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
interface OverflowTabsBarProps {
|
|
448
|
-
tabs: TabDefinition[];
|
|
449
|
-
current: string;
|
|
450
|
-
onTabChange: (name: string) => void;
|
|
451
|
-
className?: string;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Tabs as a horizontal row; any that don't fit collapse into a trailing "More"
|
|
456
|
-
* dropdown. The visible/overflow split is measured from a hidden full-width row.
|
|
457
|
-
*/
|
|
458
|
-
function OverflowTabsBar({ tabs, current, onTabChange, className }: OverflowTabsBarProps) {
|
|
459
|
-
const { t } = useUITranslation();
|
|
460
|
-
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
461
|
-
const itemRefs = useRef<Array<HTMLButtonElement | null>>([]);
|
|
462
|
-
const moreRef = useRef<HTMLButtonElement | null>(null);
|
|
463
|
-
// `count` leading tabs are shown. When `promote` is set, the active tab is pulled
|
|
464
|
-
// into the last slot (before More) and `count` counts the tabs shown before it.
|
|
465
|
-
const [layout, setLayout] = useState<{ count: number; promote: boolean }>({ count: tabs.length, promote: false });
|
|
466
|
-
|
|
467
|
-
const recompute = () => {
|
|
468
|
-
const container = containerRef.current;
|
|
469
|
-
if (!container) return;
|
|
470
|
-
const containerWidth = container.clientWidth;
|
|
471
|
-
const widths = tabs.map((_, i) => itemRefs.current[i]?.offsetWidth ?? 0);
|
|
472
|
-
const totalAll = widths.reduce((sum, w) => sum + w, 0) + TAB_GAP_PX * Math.max(0, tabs.length - 1);
|
|
473
|
-
|
|
474
|
-
// How many tabs (in order, optionally skipping one) fit within `available`.
|
|
475
|
-
const fitCount = (available: number, skipIndex: number) => {
|
|
476
|
-
let used = 0;
|
|
477
|
-
let count = 0;
|
|
478
|
-
for (let i = 0; i < tabs.length; i++) {
|
|
479
|
-
if (i === skipIndex) continue;
|
|
480
|
-
const cand = used + (count > 0 ? TAB_GAP_PX : 0) + widths[i];
|
|
481
|
-
if (cand > available) break;
|
|
482
|
-
used = cand;
|
|
483
|
-
count += 1;
|
|
484
|
-
}
|
|
485
|
-
return count;
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
let next: { count: number; promote: boolean };
|
|
489
|
-
if (totalAll <= containerWidth) {
|
|
490
|
-
next = { count: tabs.length, promote: false };
|
|
491
|
-
} else {
|
|
492
|
-
const moreWidth = moreRef.current?.offsetWidth ?? 0;
|
|
493
|
-
const naturalCount = Math.max(1, fitCount(containerWidth - moreWidth - TAB_GAP_PX, -1));
|
|
494
|
-
const activeIndex = tabs.findIndex((tab) => tab.name === current);
|
|
495
|
-
if (activeIndex < 0 || activeIndex < naturalCount) {
|
|
496
|
-
next = { count: naturalCount, promote: false };
|
|
497
|
-
} else {
|
|
498
|
-
// Active tab overflowed: reserve its slot at the end, fit leading tabs before it.
|
|
499
|
-
const leadAvailable = containerWidth - moreWidth - widths[activeIndex] - TAB_GAP_PX * 2;
|
|
500
|
-
next = { count: fitCount(leadAvailable, activeIndex), promote: true };
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
setLayout((prev) => (prev.count === next.count && prev.promote === next.promote ? prev : next));
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
// Re-measure after every render (tab/label changes) and on container resize.
|
|
507
|
-
const recomputeRef = useRef(recompute);
|
|
508
|
-
recomputeRef.current = recompute;
|
|
509
|
-
useLayoutEffect(() => {
|
|
510
|
-
recomputeRef.current();
|
|
511
|
-
});
|
|
512
|
-
useEffect(() => {
|
|
513
|
-
const container = containerRef.current;
|
|
514
|
-
if (!container || typeof ResizeObserver === 'undefined') return;
|
|
515
|
-
const observer = new ResizeObserver(() => recomputeRef.current());
|
|
516
|
-
observer.observe(container);
|
|
517
|
-
return () => observer.disconnect();
|
|
518
|
-
}, []);
|
|
519
|
-
|
|
520
|
-
const activeIndex = tabs.findIndex((tab) => tab.name === current);
|
|
521
|
-
let visible: TabDefinition[];
|
|
522
|
-
let overflow: TabDefinition[];
|
|
523
|
-
if (layout.promote && activeIndex >= 0) {
|
|
524
|
-
// Pull the active tab into the last visible slot; the tab it displaces overflows.
|
|
525
|
-
const others = tabs.filter((_, i) => i !== activeIndex);
|
|
526
|
-
visible = [...others.slice(0, layout.count), tabs[activeIndex]];
|
|
527
|
-
overflow = others.slice(layout.count);
|
|
528
|
-
} else {
|
|
529
|
-
visible = tabs.slice(0, layout.count);
|
|
530
|
-
overflow = tabs.slice(layout.count);
|
|
531
|
-
}
|
|
532
|
-
const activeInOverflow = overflow.some((tab) => tab.name === current);
|
|
533
|
-
const moreLabel = t('agent.moreTabs');
|
|
534
|
-
|
|
535
|
-
return (
|
|
536
|
-
<div ref={containerRef} className={cn('relative', className)}>
|
|
537
|
-
{/* Hidden measurement row: all tabs + More at natural width, kept separate
|
|
538
|
-
from the visible row so measuring can't feed back into the layout. */}
|
|
539
|
-
<div aria-hidden className="pointer-events-none invisible absolute start-0 top-0 flex w-max gap-1">
|
|
540
|
-
{tabs.map((tab, i) => (
|
|
541
|
-
<button
|
|
542
|
-
type="button"
|
|
543
|
-
key={tab.name}
|
|
544
|
-
tabIndex={-1}
|
|
545
|
-
ref={(el) => {
|
|
546
|
-
itemRefs.current[i] = el;
|
|
547
|
-
}}
|
|
548
|
-
className={cn(TAB_ITEM_BASE, TAB_ITEM_INACTIVE)}
|
|
549
|
-
>
|
|
550
|
-
{tab.label}
|
|
551
|
-
</button>
|
|
552
|
-
))}
|
|
553
|
-
<button type="button" tabIndex={-1} ref={moreRef} className={cn(TAB_ITEM_BASE, TAB_ITEM_INACTIVE)}>
|
|
554
|
-
{moreLabel}
|
|
555
|
-
<ChevronDownIcon className="ms-1 size-4" />
|
|
556
|
-
</button>
|
|
557
|
-
</div>
|
|
558
|
-
|
|
559
|
-
{/* Visible row */}
|
|
560
|
-
<div className="-mb-px flex gap-1 overflow-hidden border-b">
|
|
561
|
-
{visible.map((tab) => {
|
|
562
|
-
const isActive = tab.name === current;
|
|
563
|
-
return (
|
|
564
|
-
// Tab-bar primitive: raw button mirrors core TabsTrigger underline styling.
|
|
565
|
-
<button
|
|
566
|
-
type="button"
|
|
567
|
-
key={tab.name}
|
|
568
|
-
aria-current={isActive ? 'page' : undefined}
|
|
569
|
-
disabled={tab.disabled}
|
|
570
|
-
onClick={() => onTabChange(tab.name)}
|
|
571
|
-
className={cn(
|
|
572
|
-
TAB_ITEM_BASE,
|
|
573
|
-
isActive ? TAB_ITEM_ACTIVE : TAB_ITEM_INACTIVE,
|
|
574
|
-
'disabled:pointer-events-none disabled:opacity-50',
|
|
575
|
-
)}
|
|
576
|
-
>
|
|
577
|
-
{tab.label}
|
|
578
|
-
</button>
|
|
579
|
-
);
|
|
580
|
-
})}
|
|
581
|
-
|
|
582
|
-
{overflow.length > 0 && (
|
|
583
|
-
<OverflowMoreMenu
|
|
584
|
-
tabs={overflow}
|
|
585
|
-
current={current}
|
|
586
|
-
onTabChange={onTabChange}
|
|
587
|
-
label={moreLabel}
|
|
588
|
-
active={activeInOverflow}
|
|
589
|
-
/>
|
|
590
|
-
)}
|
|
591
|
-
</div>
|
|
592
|
-
</div>
|
|
593
|
-
);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
346
|
// ---------------------------------------------------------------------------
|
|
597
347
|
// Right panel tabs
|
|
598
348
|
// ---------------------------------------------------------------------------
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
3
|
import { renderWithProviders } from '../../../__tests__/test-utils.js';
|
|
4
|
-
import { AskUserWidget } from './AskUserWidget';
|
|
4
|
+
import { type AskUserOption, AskUserWidget } from './AskUserWidget';
|
|
5
5
|
|
|
6
6
|
vi.mock('../../../widgets/markdown/MarkdownRenderer', () => ({
|
|
7
7
|
MarkdownRenderer: ({ children }: { children: ReactNode }) => <>{children}</>,
|
|
@@ -17,6 +17,25 @@ function getScrollablePrompt(container: HTMLElement): HTMLElement {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
describe('AskUserWidget', () => {
|
|
20
|
+
it('does not crash when runtime options data is not an array', () => {
|
|
21
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
22
|
+
|
|
23
|
+
expect(() =>
|
|
24
|
+
renderWithProviders(
|
|
25
|
+
<AskUserWidget
|
|
26
|
+
compact
|
|
27
|
+
hideBorder
|
|
28
|
+
question="Choose an option"
|
|
29
|
+
options={'invalid options' as unknown as AskUserOption[]}
|
|
30
|
+
allowFreeResponse
|
|
31
|
+
/>,
|
|
32
|
+
),
|
|
33
|
+
).not.toThrow();
|
|
34
|
+
|
|
35
|
+
expect(warn).toHaveBeenCalledWith('[AskUserWidget] Invalid options received; rendering without options.');
|
|
36
|
+
warn.mockRestore();
|
|
37
|
+
});
|
|
38
|
+
|
|
20
39
|
it('keeps compact prompt text in a bounded scrollable area', () => {
|
|
21
40
|
const { container } = renderWithProviders(
|
|
22
41
|
<AskUserWidget
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Button, cn } from '@vertesia/ui/core';
|
|
2
|
+
import { Env } from '@vertesia/ui/env';
|
|
2
3
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
3
4
|
import { AlertCircle, CheckCircle, HelpCircle, MessageSquare, Send, XCircle } from 'lucide-react';
|
|
4
5
|
import React from 'react';
|
|
@@ -152,6 +153,21 @@ export function AskUserWidget({
|
|
|
152
153
|
|
|
153
154
|
const styles = VARIANT_STYLES[variant];
|
|
154
155
|
const DefaultIcon = VARIANT_ICONS[variant];
|
|
156
|
+
const safeOptions = Array.isArray(options) ? options : [];
|
|
157
|
+
const invalidOptionsReported = React.useRef(false);
|
|
158
|
+
|
|
159
|
+
React.useEffect(() => {
|
|
160
|
+
if (options === undefined || Array.isArray(options) || invalidOptionsReported.current) return;
|
|
161
|
+
|
|
162
|
+
invalidOptionsReported.current = true;
|
|
163
|
+
Env.logger.warn('AskUserWidget received invalid options; rendering without options', {
|
|
164
|
+
vertesia: {
|
|
165
|
+
component: 'AskUserWidget',
|
|
166
|
+
received_type: typeof options,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
console.warn('[AskUserWidget] Invalid options received; rendering without options.');
|
|
170
|
+
}, [options]);
|
|
155
171
|
|
|
156
172
|
const toggleOption = (optionId: string) => {
|
|
157
173
|
setSelectedOptions((prev) => {
|
|
@@ -232,11 +248,11 @@ export function AskUserWidget({
|
|
|
232
248
|
</div>
|
|
233
249
|
</div>
|
|
234
250
|
|
|
235
|
-
{
|
|
251
|
+
{safeOptions.length > 0 && (
|
|
236
252
|
<div className={cn('flex flex-col gap-1.5 px-3 pb-3 pt-0', optionsClassName)}>
|
|
237
253
|
{multiSelect ? (
|
|
238
254
|
<>
|
|
239
|
-
{
|
|
255
|
+
{safeOptions.map((option) => {
|
|
240
256
|
const selected = selectedOptions.has(option.id);
|
|
241
257
|
return (
|
|
242
258
|
<label
|
|
@@ -286,7 +302,7 @@ export function AskUserWidget({
|
|
|
286
302
|
</div>
|
|
287
303
|
</>
|
|
288
304
|
) : (
|
|
289
|
-
|
|
305
|
+
safeOptions.map((option) => (
|
|
290
306
|
<button
|
|
291
307
|
type="button"
|
|
292
308
|
key={option.id}
|
|
@@ -383,12 +399,12 @@ export function AskUserWidget({
|
|
|
383
399
|
</div>
|
|
384
400
|
|
|
385
401
|
{/* Options */}
|
|
386
|
-
{
|
|
402
|
+
{safeOptions.length > 0 && (
|
|
387
403
|
<div className={`px-4 pb-3 pt-1 ${optionsClassName || ''}`}>
|
|
388
404
|
{multiSelect ? (
|
|
389
405
|
/* Multi-select mode with checkboxes */
|
|
390
406
|
<div className="space-y-2">
|
|
391
|
-
{
|
|
407
|
+
{safeOptions.map((option) => (
|
|
392
408
|
<label
|
|
393
409
|
key={option.id}
|
|
394
410
|
className={`flex items-start gap-3 px-4 py-3 rounded-lg cursor-pointer transition-colors
|
|
@@ -436,7 +452,7 @@ export function AskUserWidget({
|
|
|
436
452
|
) : (
|
|
437
453
|
/* Single-select mode - always use full-width card layout for clarity */
|
|
438
454
|
<div className="flex flex-col gap-2 w-full">
|
|
439
|
-
{
|
|
455
|
+
{safeOptions.map((option) => (
|
|
440
456
|
<Button
|
|
441
457
|
variant="unstyled"
|
|
442
458
|
key={option.id}
|