@vertesia/ui 1.5.0-dev.20260722.120446Z → 1.5.0-dev.20260804.124748Z
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/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filterBar.js +1 -1
- package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.js +2 -0
- package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
- package/lib/core/components/shadcn/tabs.d.ts +12 -1
- package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/core/components/shadcn/tabs.js +12 -4
- package/lib/core/components/shadcn/tabs.js.map +1 -1
- package/lib/core/hooks/useScrollableSearch.d.ts +1 -1
- package/lib/core/hooks/useScrollableSearch.d.ts.map +1 -1
- package/lib/core/hooks/useScrollableSearch.js +15 -2
- package/lib/core/hooks/useScrollableSearch.js.map +1 -1
- package/lib/env/index.d.ts +4 -0
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.js +3 -8
- package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts +5 -1
- package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRightPanel.js +2 -2
- package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts +5 -1
- package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
- package/lib/features/agent/chat/ArtifactsTab.js +48 -11
- package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
- package/lib/features/agent/chat/DocumentEditingActionCard.d.ts +6 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.d.ts.map +1 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.js +129 -0
- package/lib/features/agent/chat/DocumentEditingActionCard.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +27 -2
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +174 -40
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +25 -10
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts +45 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js +40 -0
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +118 -58
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +23 -7
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +25 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +33 -0
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +3 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +23 -25
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts +14 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js +21 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts +30 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +53 -0
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +21 -2
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +9 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +97 -2
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts +6 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js +29 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts +33 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js +129 -0
- package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +7 -0
- package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js +11 -1
- package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +34 -10
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/agent/chat/index.d.ts +2 -1
- package/lib/features/agent/chat/index.d.ts.map +1 -1
- package/lib/features/agent/chat/index.js +3 -0
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts +8 -6
- package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.js +8 -3
- package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
- package/lib/features/store/objects/DocumentSearchResults.js +2 -2
- package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts +2 -1
- package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +90 -16
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts +16 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js +116 -0
- package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts +7 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.js +13 -0
- package/lib/features/store/objects/components/DocumentEditingLockStatus.js.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.d.ts +48 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.d.ts.map +1 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.js +720 -0
- package/lib/features/store/objects/components/DocumentEditingPanel.js.map +1 -0
- package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.js +22 -9
- package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
- package/lib/features/store/objects/components/documentArtifactRefs.d.ts +26 -0
- package/lib/features/store/objects/components/documentArtifactRefs.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentArtifactRefs.js +52 -0
- package/lib/features/store/objects/components/documentArtifactRefs.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts +4 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.js +40 -0
- package/lib/features/store/objects/components/documentEditingAgentConfig.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingPrompts.d.ts +3 -0
- package/lib/features/store/objects/components/documentEditingPrompts.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingPrompts.js +13 -0
- package/lib/features/store/objects/components/documentEditingPrompts.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingRun.d.ts +27 -0
- package/lib/features/store/objects/components/documentEditingRun.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingRun.js +126 -0
- package/lib/features/store/objects/components/documentEditingRun.js.map +1 -0
- package/lib/features/store/objects/components/documentEditingTarget.d.ts +20 -0
- package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -0
- package/lib/features/store/objects/components/documentEditingTarget.js +40 -0
- package/lib/features/store/objects/components/documentEditingTarget.js.map +1 -0
- package/lib/features/store/objects/components/index.d.ts +1 -0
- package/lib/features/store/objects/components/index.d.ts.map +1 -1
- package/lib/features/store/objects/components/index.js +1 -0
- package/lib/features/store/objects/components/index.js.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts +36 -4
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.js +53 -29
- package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
- package/lib/features/store/objects/components/useDownloadFile.d.ts +2 -1
- package/lib/features/store/objects/components/useDownloadFile.d.ts.map +1 -1
- package/lib/features/store/objects/components/useDownloadFile.js +3 -0
- package/lib/features/store/objects/components/useDownloadFile.js.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts +128 -6
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts.map +1 -1
- package/lib/features/store/objects/selection/SelectionActions.d.ts +2 -2
- package/lib/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js.map +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts +2 -2
- package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.js +5 -1
- package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.js +2 -2
- package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
- package/lib/features/store/types/ObjectSchemaEditor.d.ts +2 -2
- package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.d.ts +2 -2
- package/lib/features/store/types/SelectContentType.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.js.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.d.ts +2 -2
- package/lib/features/store/types/SelectContentTypeModal.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
- package/lib/features/store/types/TableLayoutEditor.d.ts +2 -2
- package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.d.ts +1267 -6
- package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.js +5 -0
- package/lib/features/store/types/TypeRegistry.js.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.js +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.js.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +1251 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
- package/lib/features/store/types/typeCatalogCache.d.ts +2 -2
- package/lib/features/store/types/typeCatalogCache.d.ts.map +1 -1
- package/lib/features/store/types/typeCatalogCache.js +4 -0
- package/lib/features/store/types/typeCatalogCache.js.map +1 -1
- package/lib/features/user/UserInfo.d.ts +118 -7
- package/lib/features/user/UserInfo.d.ts.map +1 -1
- package/lib/i18n/locales/ar.json +120 -2
- package/lib/i18n/locales/de.json +120 -2
- package/lib/i18n/locales/en.json +123 -1
- package/lib/i18n/locales/es.json +120 -2
- package/lib/i18n/locales/fr.json +120 -2
- package/lib/i18n/locales/it.json +120 -2
- package/lib/i18n/locales/ja.json +120 -2
- package/lib/i18n/locales/ko.json +120 -2
- package/lib/i18n/locales/pt.json +120 -2
- package/lib/i18n/locales/ru.json +120 -2
- package/lib/i18n/locales/tr.json +120 -2
- package/lib/i18n/locales/zh-TW.json +120 -2
- package/lib/i18n/locales/zh.json +120 -2
- package/lib/rich-text/EditorToolbar.d.ts +37 -0
- package/lib/rich-text/EditorToolbar.d.ts.map +1 -0
- package/lib/rich-text/EditorToolbar.js +215 -0
- package/lib/rich-text/EditorToolbar.js.map +1 -0
- package/lib/rich-text/VertesiaRichTextEditor.d.ts +26 -0
- package/lib/rich-text/VertesiaRichTextEditor.d.ts.map +1 -0
- package/lib/rich-text/VertesiaRichTextEditor.js +67 -0
- package/lib/rich-text/VertesiaRichTextEditor.js.map +1 -0
- package/lib/rich-text/index.d.ts +2 -0
- package/lib/rich-text/index.d.ts.map +1 -0
- package/lib/rich-text/index.js +2 -0
- package/lib/rich-text/index.js.map +1 -0
- package/lib/session/UserSession.d.ts +18 -4
- package/lib/session/UserSession.d.ts.map +1 -1
- package/lib/shell/apps/AppInstallationProvider.d.ts +222 -2
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/vertesia-ui-core.js +3 -3
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +35 -30
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +14 -14
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +5 -0
- package/lib/vertesia-ui-rich-text.js.map +1 -0
- package/lib/vertesia-ui-widgets.js +25 -7
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/markdown/AgentResourceResolver.d.ts +31 -0
- package/lib/widgets/markdown/AgentResourceResolver.d.ts.map +1 -0
- package/lib/widgets/markdown/AgentResourceResolver.js +39 -0
- package/lib/widgets/markdown/AgentResourceResolver.js.map +1 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.d.ts +63 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.d.ts.map +1 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.js +582 -0
- package/lib/widgets/markdown/ArtifactEditingSurface.js.map +1 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts +69 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts.map +1 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +374 -0
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js.map +1 -0
- package/lib/widgets/markdown/MarkdownLink.d.ts +3 -1
- package/lib/widgets/markdown/MarkdownLink.d.ts.map +1 -1
- package/lib/widgets/markdown/MarkdownLink.js +41 -14
- package/lib/widgets/markdown/MarkdownLink.js.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.d.ts +8 -1
- package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
- package/lib/widgets/markdown/MarkdownRenderer.js +20 -4
- package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
- package/lib/widgets/markdown/index.d.ts +5 -1
- package/lib/widgets/markdown/index.d.ts.map +1 -1
- package/lib/widgets/markdown/index.js +5 -1
- package/lib/widgets/markdown/index.js.map +1 -1
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -1
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.js +14 -2
- package/lib/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -1
- package/lib/widgets/markdown/textDiff.d.ts +52 -0
- package/lib/widgets/markdown/textDiff.d.ts.map +1 -0
- package/lib/widgets/markdown/textDiff.js +362 -0
- package/lib/widgets/markdown/textDiff.js.map +1 -0
- package/lib/widgets/markdown/useArtifactContent.d.ts +5 -3
- package/lib/widgets/markdown/useArtifactContent.d.ts.map +1 -1
- package/lib/widgets/markdown/useArtifactContent.js +6 -3
- package/lib/widgets/markdown/useArtifactContent.js.map +1 -1
- package/lib/widgets/markdown/useResolvedUrl.d.ts +1 -5
- package/lib/widgets/markdown/useResolvedUrl.d.ts.map +1 -1
- package/lib/widgets/markdown/useResolvedUrl.js +19 -31
- package/lib/widgets/markdown/useResolvedUrl.js.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts +7 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.js +62 -6
- package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +9 -0
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +20 -17
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
- package/package.json +36 -32
- package/src/__tests__/a11y.test.tsx +4 -1
- package/src/__tests__/axe-helper.ts +17 -7
- package/src/__tests__/setup.ts +25 -0
- package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
- package/src/core/components/shadcn/modal/dialog.tsx +3 -1
- package/src/core/components/shadcn/tabs.test.tsx +65 -0
- package/src/core/components/shadcn/tabs.tsx +25 -3
- package/src/core/hooks/useScrollableSearch.test.tsx +139 -0
- package/src/core/hooks/useScrollableSearch.tsx +17 -3
- package/src/env/index.ts +2 -0
- package/src/features/agent/chat/AgentChatPlaybackControls.test.tsx +2 -0
- package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +51 -6
- package/src/features/agent/chat/AgentRequestInputOverlay.tsx +5 -7
- package/src/features/agent/chat/AgentRightPanel.tsx +16 -1
- package/src/features/agent/chat/ArtifactsTab.test.tsx +55 -0
- package/src/features/agent/chat/ArtifactsTab.tsx +203 -52
- package/src/features/agent/chat/DocumentEditingActionCard.test.tsx +105 -0
- package/src/features/agent/chat/DocumentEditingActionCard.tsx +210 -0
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +432 -43
- package/src/features/agent/chat/ModernAgentConversation.tsx +352 -96
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +75 -20
- package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.test.tsx +79 -0
- package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.tsx +94 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +369 -34
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +279 -115
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +53 -4
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.test.tsx +44 -0
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +88 -0
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +2 -2
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.test.tsx +71 -0
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +3 -1
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +48 -50
- package/src/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.tsx +40 -0
- package/src/features/agent/chat/ModernAgentOutput/ResourceChip.test.tsx +148 -0
- package/src/features/agent/chat/ModernAgentOutput/ResourceChip.tsx +141 -0
- package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +33 -1
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +95 -0
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +111 -1
- package/src/features/agent/chat/ModernAgentOutput/resourceLinks.tsx +43 -0
- package/src/features/agent/chat/ModernAgentOutput/resourceSummary.test.ts +229 -0
- package/src/features/agent/chat/ModernAgentOutput/resourceSummary.ts +152 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +17 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +14 -1
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +245 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +38 -9
- package/src/features/agent/chat/index.ts +12 -0
- package/src/features/facets/PromptsFacetsNav.tsx +17 -9
- package/src/features/store/objects/DocumentSearchResults.tsx +2 -2
- package/src/features/store/objects/components/ContentOverview.tsx +220 -66
- package/src/features/store/objects/components/DocumentEditingConfigurationSelector.test.ts +34 -0
- package/src/features/store/objects/components/DocumentEditingConfigurationSelector.tsx +211 -0
- package/src/features/store/objects/components/DocumentEditingLockStatus.test.tsx +32 -0
- package/src/features/store/objects/components/DocumentEditingLockStatus.tsx +45 -0
- package/src/features/store/objects/components/DocumentEditingPanel.test.tsx +336 -0
- package/src/features/store/objects/components/DocumentEditingPanel.tsx +1236 -0
- package/src/features/store/objects/components/TextEditorPanel.test.tsx +48 -0
- package/src/features/store/objects/components/TextEditorPanel.tsx +41 -20
- package/src/features/store/objects/components/documentArtifactRefs.test.ts +65 -0
- package/src/features/store/objects/components/documentArtifactRefs.ts +72 -0
- package/src/features/store/objects/components/documentEditingAgentConfig.test.ts +28 -0
- package/src/features/store/objects/components/documentEditingAgentConfig.ts +41 -0
- package/src/features/store/objects/components/documentEditingPrompts.test.ts +26 -0
- package/src/features/store/objects/components/documentEditingPrompts.ts +12 -0
- package/src/features/store/objects/components/documentEditingRun.test.ts +176 -0
- package/src/features/store/objects/components/documentEditingRun.ts +184 -0
- package/src/features/store/objects/components/documentEditingTarget.test.ts +96 -0
- package/src/features/store/objects/components/documentEditingTarget.ts +63 -0
- package/src/features/store/objects/components/index.ts +1 -0
- package/src/features/store/objects/components/useContentPanelHooks.ts +52 -27
- package/src/features/store/objects/components/useDownloadFile.test.ts +20 -0
- package/src/features/store/objects/components/useDownloadFile.ts +5 -1
- package/src/features/store/objects/selection/ObjectsActionContext.tsx +2 -2
- package/src/features/store/objects/selection/ObjectsActionSpec.ts +2 -2
- package/src/features/store/objects/selection/SelectionActions.tsx +2 -2
- package/src/features/store/objects/selection/actions/StartWorkflowButton.tsx +2 -2
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +2 -2
- package/src/features/store/types/IntakePolicyEditor.tsx +12 -4
- package/src/features/store/types/IntakePolicyForm.tsx +25 -0
- package/src/features/store/types/ObjectSchemaEditor.tsx +2 -2
- package/src/features/store/types/SelectContentType.tsx +9 -9
- package/src/features/store/types/SelectContentTypeModal.tsx +5 -5
- package/src/features/store/types/TableLayoutEditor.tsx +2 -2
- package/src/features/store/types/TypeRegistry.ts +8 -3
- package/src/features/store/types/intake-policy-editor.logic.ts +10 -2
- package/src/features/store/types/typeCatalogCache.ts +10 -3
- package/src/i18n/locales/ar.json +120 -2
- package/src/i18n/locales/de.json +120 -2
- package/src/i18n/locales/en.json +123 -1
- package/src/i18n/locales/es.json +120 -2
- package/src/i18n/locales/fr.json +120 -2
- package/src/i18n/locales/it.json +120 -2
- package/src/i18n/locales/ja.json +120 -2
- package/src/i18n/locales/ko.json +120 -2
- package/src/i18n/locales/pt.json +120 -2
- package/src/i18n/locales/ru.json +120 -2
- package/src/i18n/locales/tr.json +120 -2
- package/src/i18n/locales/zh-TW.json +120 -2
- package/src/i18n/locales/zh.json +120 -2
- package/src/rich-text/EditorToolbar.tsx +708 -0
- package/src/rich-text/VertesiaRichTextEditor.test.tsx +211 -0
- package/src/rich-text/VertesiaRichTextEditor.tsx +241 -0
- package/src/rich-text/index.ts +9 -0
- package/src/session/UserSession.test.ts +11 -11
- package/src/shell/login/InviteAcceptModal.tsx +4 -4
- package/src/widgets/markdown/AgentResourceResolver.test.ts +24 -0
- package/src/widgets/markdown/AgentResourceResolver.tsx +70 -0
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +541 -0
- package/src/widgets/markdown/ArtifactEditingSurface.tsx +878 -0
- package/src/widgets/markdown/CollaborativeMarkdownRenderer.test.tsx +484 -0
- package/src/widgets/markdown/CollaborativeMarkdownRenderer.tsx +825 -0
- package/src/widgets/markdown/MarkdownLink.test.tsx +122 -0
- package/src/widgets/markdown/MarkdownLink.tsx +102 -17
- package/src/widgets/markdown/MarkdownRenderer.tsx +30 -3
- package/src/widgets/markdown/index.ts +39 -1
- package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +15 -2
- package/src/widgets/markdown/textDiff.test.ts +156 -0
- package/src/widgets/markdown/textDiff.ts +399 -0
- package/src/widgets/markdown/useArtifactContent.ts +9 -3
- package/src/widgets/markdown/useResolvedUrl.test.ts +29 -40
- package/src/widgets/markdown/useResolvedUrl.ts +33 -35
- package/src/widgets/monacoEditor/MonacoEditor.tsx +83 -7
- package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +26 -0
- package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +23 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/ui",
|
|
3
|
-
"version": "1.5.0-dev.
|
|
3
|
+
"version": "1.5.0-dev.20260804.124748Z",
|
|
4
4
|
"description": "Vertesia UI components and and hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -24,24 +24,24 @@
|
|
|
24
24
|
"@floating-ui/dom": "^1.8.0",
|
|
25
25
|
"@floating-ui/react": "^0.27.20",
|
|
26
26
|
"@monaco-editor/react": "^4.7.0",
|
|
27
|
-
"@radix-ui/react-checkbox": "^1.3.
|
|
28
|
-
"@radix-ui/react-collapsible": "^1.1.
|
|
29
|
-
"@radix-ui/react-dialog": "^1.1.
|
|
30
|
-
"@radix-ui/react-direction": "^1.1.
|
|
31
|
-
"@radix-ui/react-dismissable-layer": "^1.1.
|
|
32
|
-
"@radix-ui/react-dropdown-menu": "^2.1.
|
|
33
|
-
"@radix-ui/react-focus-guards": "^1.1.
|
|
34
|
-
"@radix-ui/react-focus-scope": "^1.1.
|
|
35
|
-
"@radix-ui/react-label": "^2.1.
|
|
36
|
-
"@radix-ui/react-popover": "^1.1.
|
|
37
|
-
"@radix-ui/react-portal": "^1.1.
|
|
38
|
-
"@radix-ui/react-radio-group": "^1.4.
|
|
39
|
-
"@radix-ui/react-separator": "^1.1.
|
|
40
|
-
"@radix-ui/react-slider": "^1.4.
|
|
41
|
-
"@radix-ui/react-slot": "^1.3.
|
|
42
|
-
"@radix-ui/react-switch": "^1.3.
|
|
43
|
-
"@radix-ui/react-tabs": "^1.1.
|
|
44
|
-
"@radix-ui/react-tooltip": "^1.2.
|
|
27
|
+
"@radix-ui/react-checkbox": "^1.3.11",
|
|
28
|
+
"@radix-ui/react-collapsible": "^1.1.20",
|
|
29
|
+
"@radix-ui/react-dialog": "^1.1.23",
|
|
30
|
+
"@radix-ui/react-direction": "^1.1.4",
|
|
31
|
+
"@radix-ui/react-dismissable-layer": "^1.1.19",
|
|
32
|
+
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
|
33
|
+
"@radix-ui/react-focus-guards": "^1.1.6",
|
|
34
|
+
"@radix-ui/react-focus-scope": "^1.1.16",
|
|
35
|
+
"@radix-ui/react-label": "^2.1.15",
|
|
36
|
+
"@radix-ui/react-popover": "^1.1.23",
|
|
37
|
+
"@radix-ui/react-portal": "^1.1.17",
|
|
38
|
+
"@radix-ui/react-radio-group": "^1.4.7",
|
|
39
|
+
"@radix-ui/react-separator": "^1.1.15",
|
|
40
|
+
"@radix-ui/react-slider": "^1.4.7",
|
|
41
|
+
"@radix-ui/react-slot": "^1.3.3",
|
|
42
|
+
"@radix-ui/react-switch": "^1.3.7",
|
|
43
|
+
"@radix-ui/react-tabs": "^1.1.21",
|
|
44
|
+
"@radix-ui/react-tooltip": "^1.2.16",
|
|
45
45
|
"ajv": "^8.20.0",
|
|
46
46
|
"ajv-formats": "^3.0.1",
|
|
47
47
|
"aria-hidden": "^1.2.6",
|
|
@@ -52,16 +52,15 @@
|
|
|
52
52
|
"debounce": "^3.0.0",
|
|
53
53
|
"dompurify": "^3.4.12",
|
|
54
54
|
"fast-xml-parser": "^5.10.1",
|
|
55
|
-
"fast-xml-validator": "^1.2.0",
|
|
56
55
|
"firebase": "^12.16.0",
|
|
57
56
|
"framer-motion": "^12.42.2",
|
|
58
57
|
"i18next": "^26.3.6",
|
|
59
58
|
"jwt-decode": "^4.0.0",
|
|
60
|
-
"katex": "^0.
|
|
59
|
+
"katex": "^0.18.1",
|
|
61
60
|
"lodash-es": "^4.18.1",
|
|
62
|
-
"lucide-react": "^1.
|
|
61
|
+
"lucide-react": "^1.27.0",
|
|
63
62
|
"mermaid": "^11.16.0",
|
|
64
|
-
"monaco-editor": "^0.
|
|
63
|
+
"monaco-editor": "^0.56.0",
|
|
65
64
|
"motion": "^12.42.2",
|
|
66
65
|
"papaparse": "^5.5.4",
|
|
67
66
|
"react": "19.2.7",
|
|
@@ -69,7 +68,7 @@
|
|
|
69
68
|
"react-date-picker": "^12.0.2",
|
|
70
69
|
"react-dom": "19.2.7",
|
|
71
70
|
"react-error-boundary": "^6.1.2",
|
|
72
|
-
"react-i18next": "^17.0.
|
|
71
|
+
"react-i18next": "^17.0.11",
|
|
73
72
|
"react-markdown": "^10.1.0",
|
|
74
73
|
"react-pdf": "^10.4.1",
|
|
75
74
|
"react-remove-scroll": "^2.7.2",
|
|
@@ -87,13 +86,14 @@
|
|
|
87
86
|
"tailwind-merge": "^3.6.0",
|
|
88
87
|
"ts-md5": "^2.0.1",
|
|
89
88
|
"unist-util-visit": "^5.1.0",
|
|
90
|
-
"vega": "^6.
|
|
89
|
+
"vega": "^6.3.1",
|
|
91
90
|
"vega-embed": "^7.1.0",
|
|
92
91
|
"vega-lite": "^6.4.3",
|
|
93
|
-
"@vertesia/client": "1.5.0-dev.
|
|
94
|
-
"@vertesia/
|
|
95
|
-
"@vertesia/fusion-ux": "1.5.0-dev.
|
|
96
|
-
"@vertesia/
|
|
92
|
+
"@vertesia/client": "1.5.0-dev.20260804.124748Z",
|
|
93
|
+
"@vertesia/common": "1.5.0-dev.20260804.124748Z",
|
|
94
|
+
"@vertesia/fusion-ux": "1.5.0-dev.20260804.124748Z",
|
|
95
|
+
"@vertesia/rich-text": "1.5.0-dev.20260804.124748Z",
|
|
96
|
+
"@vertesia/json": "1.5.0-dev.20260804.124748Z"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@testing-library/react": "^16.3.2",
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"@types/react-dom": "19.2.3",
|
|
107
107
|
"axe-core": "^4.12.1",
|
|
108
108
|
"culori": "^4.0.2",
|
|
109
|
-
"i18next-cli": "^1.
|
|
109
|
+
"i18next-cli": "^1.66.2",
|
|
110
110
|
"jsdom": "^29.1.1",
|
|
111
|
-
"rolldown": "1.
|
|
111
|
+
"rolldown": "1.2.0",
|
|
112
112
|
"typescript": "^6.0.3",
|
|
113
113
|
"vitest": "^4.1.10",
|
|
114
114
|
"vitest-axe": "^0.1.0",
|
|
@@ -150,6 +150,10 @@
|
|
|
150
150
|
"types": "./lib/widgets/index.d.ts",
|
|
151
151
|
"default": "./lib/widgets/index.js"
|
|
152
152
|
},
|
|
153
|
+
"./rich-text": {
|
|
154
|
+
"types": "./lib/rich-text/index.d.ts",
|
|
155
|
+
"default": "./lib/rich-text/index.js"
|
|
156
|
+
},
|
|
153
157
|
"./code": {
|
|
154
158
|
"types": "./lib/code/index.d.ts",
|
|
155
159
|
"default": "./lib/code/index.js"
|
|
@@ -180,7 +184,7 @@
|
|
|
180
184
|
"url": "https://github.com/vertesia/composableai.git",
|
|
181
185
|
"directory": "packages/ui"
|
|
182
186
|
},
|
|
183
|
-
"gitHead": "
|
|
187
|
+
"gitHead": "87ac9166db2b38bd1be6e37adf0414ea83e402ee",
|
|
184
188
|
"scripts": {
|
|
185
189
|
"clean:lib": "rimraf ./lib ./tsconfig.tsbuildinfo",
|
|
186
190
|
"clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo",
|
|
@@ -320,7 +320,10 @@ describe('@vertesia/ui accessibility (axe)', () => {
|
|
|
320
320
|
const { baseElement } = renderWithProviders(<Harness />);
|
|
321
321
|
// Radix portals the dialog into document.body, not the render container.
|
|
322
322
|
// noCloseButton avoids the Button.alt -> aria-label gap (deferred to Section 3).
|
|
323
|
-
|
|
323
|
+
// Radix focus guards are intentionally focusable, visually hidden sentinels. Newer
|
|
324
|
+
// axe-core versions flag their tabindex + aria-hidden combination even though they
|
|
325
|
+
// are infrastructure outside the dialog's accessible content.
|
|
326
|
+
expect(await axe(baseElement, { exclude: ['[data-radix-focus-guard]'] })).toHaveNoViolations();
|
|
324
327
|
});
|
|
325
328
|
|
|
326
329
|
it('Table with column headers and sortable button has no violations', async () => {
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import axeCore, { type AxeResults, type RunOptions } from 'axe-core';
|
|
2
2
|
import { axe as baseAxe } from 'vitest-axe';
|
|
3
3
|
|
|
4
|
+
const RUN_OPTIONS: RunOptions = {
|
|
5
|
+
rules: {
|
|
6
|
+
'color-contrast': { enabled: false },
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export interface AxeTestOptions {
|
|
11
|
+
/** Selectors to omit from this specific axe run while testing the rest of the container. */
|
|
12
|
+
exclude?: string[];
|
|
13
|
+
}
|
|
14
|
+
|
|
4
15
|
/**
|
|
5
16
|
* Project-wide axe runner.
|
|
6
17
|
*
|
|
@@ -14,10 +25,9 @@ import { axe as baseAxe } from 'vitest-axe';
|
|
|
14
25
|
* Lives in a `.ts` file (not `.tsx`) to keep its module init free of React/JSX
|
|
15
26
|
* resolution concerns.
|
|
16
27
|
*/
|
|
17
|
-
export function axe(container: Element | string): Promise<AxeResults> {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
28
|
+
export function axe(container: Element | string, options: AxeTestOptions = {}): Promise<AxeResults> {
|
|
29
|
+
if (options.exclude?.length && typeof container !== 'string') {
|
|
30
|
+
return axeCore.run({ include: [container], exclude: options.exclude }, RUN_OPTIONS);
|
|
31
|
+
}
|
|
32
|
+
return baseAxe(container, RUN_OPTIONS);
|
|
23
33
|
}
|
package/src/__tests__/setup.ts
CHANGED
|
@@ -72,3 +72,28 @@ if (typeof globalThis.ResizeObserver === 'undefined') {
|
|
|
72
72
|
(globalThis as unknown as { ResizeObserver: typeof ResizeObserverPolyfill }).ResizeObserver =
|
|
73
73
|
ResizeObserverPolyfill;
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
// Chart and Mermaid modules probe canvas support during import. jsdom's default
|
|
77
|
+
// implementation only logs a noisy "not implemented" error, so return the same
|
|
78
|
+
// unsupported value without polluting otherwise successful UI test output.
|
|
79
|
+
if (typeof HTMLCanvasElement !== 'undefined') {
|
|
80
|
+
Object.defineProperty(HTMLCanvasElement.prototype, 'getContext', {
|
|
81
|
+
configurable: true,
|
|
82
|
+
value: () => null,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ProseMirror asks the browser for caret geometry during pointer/keyboard input.
|
|
87
|
+
// jsdom has no layout engine, so provide stable empty geometry for interaction tests.
|
|
88
|
+
if (typeof document !== 'undefined' && typeof document.elementFromPoint !== 'function') {
|
|
89
|
+
document.elementFromPoint = () => document.querySelector('.ProseMirror') ?? document.body;
|
|
90
|
+
}
|
|
91
|
+
if (typeof Range !== 'undefined') {
|
|
92
|
+
const emptyRect = () => new DOMRect(0, 0, 0, 0);
|
|
93
|
+
if (typeof Range.prototype.getBoundingClientRect !== 'function') {
|
|
94
|
+
Range.prototype.getBoundingClientRect = emptyRect;
|
|
95
|
+
}
|
|
96
|
+
if (typeof Range.prototype.getClientRects !== 'function') {
|
|
97
|
+
Range.prototype.getClientRects = () => [] as unknown as DOMRectList;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -16,7 +16,7 @@ interface ModalProps {
|
|
|
16
16
|
className?: string;
|
|
17
17
|
allowOverflow?: boolean;
|
|
18
18
|
disableCloseOnClickOutside?: boolean;
|
|
19
|
-
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
19
|
+
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
20
20
|
action?: React.ReactNode;
|
|
21
21
|
}
|
|
22
22
|
const ModalContext = createContext<boolean>(false);
|
|
@@ -54,6 +54,8 @@ export function Modal({
|
|
|
54
54
|
return 'max-w-[80vw] md:max-w-[60vw]';
|
|
55
55
|
case 'xl':
|
|
56
56
|
return 'max-w-[95vw] lg:max-w-[80vw]';
|
|
57
|
+
case 'full':
|
|
58
|
+
return 'h-[calc(100vh-2rem)] max-w-[calc(100vw-2rem)]';
|
|
57
59
|
default:
|
|
58
60
|
return 'max-w-[60vw] lg:max-w-[40vw]';
|
|
59
61
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { Tabs, TabsBar, TabsPanel } from './tabs';
|
|
4
|
+
|
|
5
|
+
const TABS = [
|
|
6
|
+
{ name: 'first', label: 'First', href: '#first', content: <div>First panel</div> },
|
|
7
|
+
{ name: 'second', label: 'Second', href: '#second', content: <div>Second panel</div> },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
function renderTabs(canChangeTab?: (nextTab: string, currentTab?: string) => boolean) {
|
|
11
|
+
return render(
|
|
12
|
+
<Tabs tabs={TABS} defaultValue="first" canChangeTab={canChangeTab}>
|
|
13
|
+
<TabsBar />
|
|
14
|
+
<TabsPanel />
|
|
15
|
+
</Tabs>,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('Tabs canChangeTab', () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
window.history.replaceState(null, '', '/');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('cancels the switch and leaves the hash alone when the guard returns false', () => {
|
|
25
|
+
const canChangeTab = vi.fn().mockReturnValue(false);
|
|
26
|
+
renderTabs(canChangeTab);
|
|
27
|
+
|
|
28
|
+
fireEvent.click(screen.getByRole('tab', { name: 'Second' }));
|
|
29
|
+
|
|
30
|
+
expect(canChangeTab).toHaveBeenCalledWith('second', 'first');
|
|
31
|
+
expect(screen.getByText('First panel')).toBeDefined();
|
|
32
|
+
expect(screen.queryByText('Second panel')).toBeNull();
|
|
33
|
+
expect(window.location.hash).toBe('');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('allows the switch when the guard returns true', () => {
|
|
37
|
+
const canChangeTab = vi.fn().mockReturnValue(true);
|
|
38
|
+
renderTabs(canChangeTab);
|
|
39
|
+
|
|
40
|
+
fireEvent.click(screen.getByRole('tab', { name: 'Second' }));
|
|
41
|
+
|
|
42
|
+
expect(screen.getByText('Second panel')).toBeDefined();
|
|
43
|
+
expect(window.location.hash).toBe('#second');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('does not consult the guard when the active tab is clicked again', () => {
|
|
47
|
+
const canChangeTab = vi.fn().mockReturnValue(false);
|
|
48
|
+
renderTabs(canChangeTab);
|
|
49
|
+
|
|
50
|
+
fireEvent.click(screen.getByRole('tab', { name: 'First' }));
|
|
51
|
+
|
|
52
|
+
expect(canChangeTab).not.toHaveBeenCalled();
|
|
53
|
+
expect(screen.getByText('First panel')).toBeDefined();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('still switches from a hash change so a cancelled switch can be resumed', () => {
|
|
57
|
+
const canChangeTab = vi.fn().mockReturnValue(false);
|
|
58
|
+
renderTabs(canChangeTab);
|
|
59
|
+
|
|
60
|
+
window.location.hash = 'second';
|
|
61
|
+
fireEvent(window, new HashChangeEvent('hashchange'));
|
|
62
|
+
|
|
63
|
+
expect(screen.getByText('Second panel')).toBeDefined();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -15,6 +15,17 @@ export interface Tab {
|
|
|
15
15
|
is_allowed?: boolean;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Guard consulted before switching to another tab. Return `false` to cancel the switch — the active
|
|
20
|
+
* tab, the URL hash and the browser history are all left untouched, so the guard can hold the user
|
|
21
|
+
* on a tab that has unsaved changes while a confirmation is shown.
|
|
22
|
+
*
|
|
23
|
+
* It is only called when the target tab differs from the active one, but it may be called more than
|
|
24
|
+
* once for a single attempted switch (a click reaches both the trigger and the Radix root), so any
|
|
25
|
+
* side effect it performs must be idempotent.
|
|
26
|
+
*/
|
|
27
|
+
export type CanChangeTab = (nextTab: string, currentTab?: string) => boolean;
|
|
28
|
+
|
|
18
29
|
const TabsContext = React.createContext<{
|
|
19
30
|
size?: number;
|
|
20
31
|
tabs?: Tab[];
|
|
@@ -23,6 +34,7 @@ const TabsContext = React.createContext<{
|
|
|
23
34
|
responsive?: boolean;
|
|
24
35
|
variant?: 'tabs' | 'pills';
|
|
25
36
|
updateHash?: boolean;
|
|
37
|
+
canChangeTab?: CanChangeTab;
|
|
26
38
|
}>({
|
|
27
39
|
size: undefined,
|
|
28
40
|
tabs: undefined,
|
|
@@ -45,6 +57,7 @@ interface TabsProps {
|
|
|
45
57
|
responsive?: boolean;
|
|
46
58
|
variant?: 'tabs' | 'pills';
|
|
47
59
|
updateHash?: boolean;
|
|
60
|
+
canChangeTab?: CanChangeTab;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
const Tabs = ({
|
|
@@ -59,6 +72,7 @@ const Tabs = ({
|
|
|
59
72
|
responsive = false,
|
|
60
73
|
variant = 'tabs',
|
|
61
74
|
updateHash = true,
|
|
75
|
+
canChangeTab,
|
|
62
76
|
}: TabsProps) => {
|
|
63
77
|
// Filter tabs based on is_allowed (undefined or true means visible)
|
|
64
78
|
const visibleTabs = React.useMemo(
|
|
@@ -121,6 +135,9 @@ const Tabs = ({
|
|
|
121
135
|
|
|
122
136
|
const handleValueChange = React.useCallback(
|
|
123
137
|
(newValue: string) => {
|
|
138
|
+
// Bail before touching the value or the history so a cancelled switch is a no-op.
|
|
139
|
+
if (newValue !== value && canChangeTab && !canChangeTab(newValue, value)) return;
|
|
140
|
+
|
|
124
141
|
setValue(newValue);
|
|
125
142
|
|
|
126
143
|
// Update the URL hash when tab changes (only if updateHash is true and not controlled by parent)
|
|
@@ -135,7 +152,7 @@ const Tabs = ({
|
|
|
135
152
|
onTabChange(newValue);
|
|
136
153
|
}
|
|
137
154
|
},
|
|
138
|
-
[current, onTabChange, updateHash],
|
|
155
|
+
[current, onTabChange, updateHash, canChangeTab, value],
|
|
139
156
|
);
|
|
140
157
|
|
|
141
158
|
const setTab = React.useCallback(
|
|
@@ -155,6 +172,7 @@ const Tabs = ({
|
|
|
155
172
|
responsive: responsive,
|
|
156
173
|
variant,
|
|
157
174
|
updateHash,
|
|
175
|
+
canChangeTab,
|
|
158
176
|
}}
|
|
159
177
|
>
|
|
160
178
|
<TabsPrimitive.Root
|
|
@@ -176,13 +194,17 @@ interface TabsBarProps {
|
|
|
176
194
|
}
|
|
177
195
|
|
|
178
196
|
const TabsBar = ({ className, sticky, direction }: TabsBarProps) => {
|
|
179
|
-
const { tabs, size, current, setTab, responsive, variant, updateHash } =
|
|
197
|
+
const { tabs, size, current, setTab, responsive, variant, updateHash, canChangeTab } =
|
|
198
|
+
React.useContext(TabsContext);
|
|
180
199
|
|
|
181
200
|
const fullWidth = size !== 0;
|
|
182
201
|
|
|
183
202
|
const handleTabChange = React.useCallback(
|
|
184
203
|
(tabName: string) => {
|
|
185
204
|
if (!tabs || !setTab) return;
|
|
205
|
+
// Consulted here too: this path pushes the tab href before `setTab` reaches the guard in
|
|
206
|
+
// `Tabs`, so a cancelled switch would otherwise leave the URL pointing at the other tab.
|
|
207
|
+
if (tabName !== current && canChangeTab && !canChangeTab(tabName, current)) return;
|
|
186
208
|
|
|
187
209
|
const tab = tabs.find((t) => t.name === tabName);
|
|
188
210
|
|
|
@@ -194,7 +216,7 @@ const TabsBar = ({ className, sticky, direction }: TabsBarProps) => {
|
|
|
194
216
|
|
|
195
217
|
setTab(tabName);
|
|
196
218
|
},
|
|
197
|
-
[tabs, setTab, updateHash],
|
|
219
|
+
[tabs, setTab, updateHash, canChangeTab, current],
|
|
198
220
|
);
|
|
199
221
|
|
|
200
222
|
if (!tabs || !setTab) {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { act, render } from '@testing-library/react';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { type ScrollableSearchResult, useDefaultScrollableSearch } from './useScrollableSearch';
|
|
5
|
+
|
|
6
|
+
beforeAll(() => {
|
|
7
|
+
// jsdom has no IntersectionObserver; the hook only needs it constructible.
|
|
8
|
+
vi.stubGlobal(
|
|
9
|
+
'IntersectionObserver',
|
|
10
|
+
class {
|
|
11
|
+
observe() {}
|
|
12
|
+
unobserve() {}
|
|
13
|
+
disconnect() {}
|
|
14
|
+
},
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Regression tests for the infinite request loop: callers pass an INLINE search
|
|
20
|
+
* closure (new identity every render). The fetch effect must not depend on that
|
|
21
|
+
* identity, otherwise every completed request re-triggers the effect forever.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
type Item = { id: number };
|
|
25
|
+
|
|
26
|
+
function flush(): Promise<void> {
|
|
27
|
+
// Drain the microtask queue so pending search promises settle.
|
|
28
|
+
return act(() => Promise.resolve());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function Harness({
|
|
32
|
+
searchFn,
|
|
33
|
+
onApi,
|
|
34
|
+
}: {
|
|
35
|
+
searchFn: (payload: unknown, offset: number, limit: number) => Promise<Item[]>;
|
|
36
|
+
onApi: (api: ScrollableSearchResult<Item, unknown, number>) => void;
|
|
37
|
+
}) {
|
|
38
|
+
const loadMoreRef = useRef<HTMLDivElement>(null);
|
|
39
|
+
// Unrelated state to force extra re-renders, as a real page would.
|
|
40
|
+
const [, setTick] = useState(0);
|
|
41
|
+
const api = useDefaultScrollableSearch<Item, unknown>({
|
|
42
|
+
// Inline closure ON PURPOSE — new identity on every render, like real callers.
|
|
43
|
+
async search(payload, offset, limit) {
|
|
44
|
+
return searchFn(payload, offset, limit);
|
|
45
|
+
},
|
|
46
|
+
pageSize: 2,
|
|
47
|
+
nextPageTrigger: loadMoreRef,
|
|
48
|
+
payload: {},
|
|
49
|
+
});
|
|
50
|
+
onApi(api);
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
<button type="button" data-testid="rerender" onClick={() => setTick((t) => t + 1)} />
|
|
54
|
+
<div ref={loadMoreRef} />
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function setup(searchFn: (payload: unknown, offset: number, limit: number) => Promise<Item[]>) {
|
|
60
|
+
let api!: ScrollableSearchResult<Item, unknown, number>;
|
|
61
|
+
const utils = render(
|
|
62
|
+
<Harness
|
|
63
|
+
searchFn={searchFn}
|
|
64
|
+
onApi={(a) => {
|
|
65
|
+
api = a;
|
|
66
|
+
}}
|
|
67
|
+
/>,
|
|
68
|
+
);
|
|
69
|
+
return { ...utils, getApi: () => api };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
describe('useDefaultScrollableSearch', () => {
|
|
73
|
+
it('fetches exactly once on mount despite inline search closures and re-renders', async () => {
|
|
74
|
+
const searchFn = vi.fn(async () => [{ id: 1 }, { id: 2 }]);
|
|
75
|
+
const { getApi } = setup(searchFn);
|
|
76
|
+
|
|
77
|
+
await flush();
|
|
78
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
79
|
+
expect(getApi().result).toEqual([{ id: 1 }, { id: 2 }]);
|
|
80
|
+
|
|
81
|
+
// Extra render cycles (state updates elsewhere on the page) must NOT re-fetch.
|
|
82
|
+
await flush();
|
|
83
|
+
await flush();
|
|
84
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('searchMore appends the next page (single extra request)', async () => {
|
|
88
|
+
const pages: Item[][] = [[{ id: 1 }, { id: 2 }], [{ id: 3 }]];
|
|
89
|
+
const searchFn = vi.fn(async (_p: unknown, offset: number) => pages[offset / 2] ?? []);
|
|
90
|
+
const { getApi } = setup(searchFn);
|
|
91
|
+
await flush();
|
|
92
|
+
|
|
93
|
+
act(() => getApi().searchMore());
|
|
94
|
+
await flush();
|
|
95
|
+
|
|
96
|
+
expect(searchFn).toHaveBeenCalledTimes(2);
|
|
97
|
+
expect(getApi().result).toEqual([{ id: 1 }, { id: 2 }, { id: 3 }]);
|
|
98
|
+
// Page of 1 < pageSize still probes once more only when triggered — no auto loop.
|
|
99
|
+
await flush();
|
|
100
|
+
expect(searchFn).toHaveBeenCalledTimes(2);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('refresh() re-fetches even on the first page (same payload, same page)', async () => {
|
|
104
|
+
const searchFn = vi.fn(async () => [{ id: 1 }]);
|
|
105
|
+
const { getApi } = setup(searchFn);
|
|
106
|
+
await flush();
|
|
107
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
108
|
+
|
|
109
|
+
act(() => getApi().refresh());
|
|
110
|
+
await flush();
|
|
111
|
+
expect(searchFn).toHaveBeenCalledTimes(2);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('empty result stops pagination (hasMore=false) and does not re-fetch', async () => {
|
|
115
|
+
const searchFn = vi.fn(async () => []);
|
|
116
|
+
const { getApi } = setup(searchFn);
|
|
117
|
+
await flush();
|
|
118
|
+
|
|
119
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(getApi().hasMore).toBe(false);
|
|
121
|
+
|
|
122
|
+
act(() => getApi().searchMore());
|
|
123
|
+
await flush();
|
|
124
|
+
// nextPage is null — searchMore is a no-op.
|
|
125
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('a failing search sets error once and does not retry in a loop', async () => {
|
|
129
|
+
const searchFn = vi.fn(async () => {
|
|
130
|
+
throw new Error('boom');
|
|
131
|
+
});
|
|
132
|
+
const { getApi } = setup(searchFn);
|
|
133
|
+
await flush();
|
|
134
|
+
await flush();
|
|
135
|
+
|
|
136
|
+
expect(getApi().error?.message).toBe('boom');
|
|
137
|
+
expect(searchFn).toHaveBeenCalledTimes(1);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -48,7 +48,7 @@ interface ScrollableSearchOptions<ResultT, PayloadT, PageT = number> {
|
|
|
48
48
|
nextPageTrigger: React.RefObject<HTMLElement | null>;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
interface ScrollableSearchResult<ResultT, PayloadT, PageT = number> {
|
|
51
|
+
export interface ScrollableSearchResult<ResultT, PayloadT, PageT = number> {
|
|
52
52
|
/**
|
|
53
53
|
* Initiates a new search with the given payload
|
|
54
54
|
* @param payload The search payload
|
|
@@ -105,15 +105,27 @@ export function useScrollableSearch<ResultT, PayloadT, PageT = number>(
|
|
|
105
105
|
const [results, setResults] = useState<ResultT[]>([]);
|
|
106
106
|
const [nextPage, setNextPage] = useState<PageT | null>(null);
|
|
107
107
|
const [isSearching, setIsSearching] = useState(false);
|
|
108
|
+
// Bumped by search()/refresh() so the fetch effect re-runs even when the
|
|
109
|
+
// payload/page state is unchanged (e.g. refresh on the first page).
|
|
110
|
+
const [refreshTick, setRefreshTick] = useState(0);
|
|
108
111
|
|
|
109
112
|
// Track current request to prevent stale results
|
|
110
113
|
const requestIdRef = useRef(0);
|
|
111
114
|
|
|
115
|
+
// Latest-ref for the search function: callers routinely pass an inline
|
|
116
|
+
// closure, which gets a new identity on every render. Depending on it in
|
|
117
|
+
// the fetch effect made every completed request re-trigger the effect —
|
|
118
|
+
// an infinite request loop. The ref always points at the latest closure
|
|
119
|
+
// without participating in the effect's dependencies.
|
|
120
|
+
const searchFnRef = useRef(opts.search);
|
|
121
|
+
searchFnRef.current = opts.search;
|
|
122
|
+
|
|
112
123
|
const search = (payload: PayloadT) => {
|
|
113
124
|
setPage(null);
|
|
114
125
|
setResults([]); // Clear old results immediately
|
|
115
126
|
setNextPage(null);
|
|
116
127
|
setLastPayload(payload);
|
|
128
|
+
setRefreshTick((tick) => tick + 1);
|
|
117
129
|
};
|
|
118
130
|
|
|
119
131
|
const searchMore = () => {
|
|
@@ -122,13 +134,15 @@ export function useScrollableSearch<ResultT, PayloadT, PageT = number>(
|
|
|
122
134
|
}
|
|
123
135
|
};
|
|
124
136
|
|
|
137
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: refreshTick is an intentional external trigger — refresh() bumps it to re-run the fetch when payload/page are unchanged
|
|
125
138
|
useEffect(() => {
|
|
126
139
|
// Increment request ID to mark previous requests as stale
|
|
127
140
|
requestIdRef.current += 1;
|
|
128
141
|
const currentRequestId = requestIdRef.current;
|
|
129
142
|
|
|
130
143
|
setIsSearching(true);
|
|
131
|
-
|
|
144
|
+
searchFnRef
|
|
145
|
+
.current(lastPayload, page, pageSize)
|
|
132
146
|
.then((r) => {
|
|
133
147
|
// Only update state if this is still the current request
|
|
134
148
|
if (currentRequestId !== requestIdRef.current) {
|
|
@@ -158,7 +172,7 @@ export function useScrollableSearch<ResultT, PayloadT, PageT = number>(
|
|
|
158
172
|
setIsSearching(false);
|
|
159
173
|
}
|
|
160
174
|
});
|
|
161
|
-
}, [...dependencies, lastPayload,
|
|
175
|
+
}, [...dependencies, lastPayload, refreshTick, page, pageSize]);
|
|
162
176
|
|
|
163
177
|
// Intersection observer for infinite scrolling
|
|
164
178
|
useIntersectionObserver(
|
package/src/env/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface EnvProps {
|
|
|
17
17
|
sts: string; // Security Token Service endpoint
|
|
18
18
|
git?: string; // Smart HTTP app source git endpoint
|
|
19
19
|
mcp?: string;
|
|
20
|
+
/** Appgen app-gateway endpoint (serves live development previews and app bundles). */
|
|
21
|
+
gateway?: string;
|
|
20
22
|
};
|
|
21
23
|
firebase?: {
|
|
22
24
|
apiKey: string;
|
|
@@ -24,6 +24,8 @@ describe('AgentChatPlaybackControls', () => {
|
|
|
24
24
|
<AgentChatPlaybackControls cursor="live" messages={messages} onChangeCursor={onChangeCursor} />,
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
+
expect(screen.getByText('Debug')).toBeTruthy();
|
|
28
|
+
|
|
27
29
|
fireEvent.click(screen.getByRole('button', { name: 'Jump to first message' }));
|
|
28
30
|
|
|
29
31
|
expect(onChangeCursor).toHaveBeenCalledWith(0);
|