@vertesia/ui 1.5.0-dev.20260725.083715Z → 1.5.0-dev.20260806.125520Z
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/ComboBox.d.ts.map +1 -1
- package/lib/core/components/ComboBox.js +4 -4
- package/lib/core/components/ComboBox.js.map +1 -1
- package/lib/core/components/FileUpload.js.map +1 -1
- package/lib/core/components/MenuList.d.ts +2 -1
- package/lib/core/components/MenuList.d.ts.map +1 -1
- package/lib/core/components/TagsInput.js +1 -1
- package/lib/core/components/popup/PopupController.d.ts.map +1 -1
- package/lib/core/components/popup/PopupController.js.map +1 -1
- package/lib/core/components/popup/position.js.map +1 -1
- package/lib/core/components/popup/utils.js.map +1 -1
- package/lib/core/components/shadcn/LanguageSwitcher.js.map +1 -1
- package/lib/core/components/shadcn/MessageBox.js.map +1 -1
- package/lib/core/components/shadcn/Panel.js +1 -1
- package/lib/core/components/shadcn/badge.d.ts +2 -2
- package/lib/core/components/shadcn/button.d.ts +2 -2
- package/lib/core/components/shadcn/button.js +1 -1
- package/lib/core/components/shadcn/command.d.ts +4 -4
- package/lib/core/components/shadcn/command.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/DynamicLabel.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/SelectCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/SelectCombobox.js +1 -1
- package/lib/core/components/shadcn/filters/comboBox/StringListCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/TextCombobox.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filter/dateFilter.js +1 -1
- package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/core/components/shadcn/filters/filters.js.map +1 -1
- package/lib/core/components/shadcn/input.d.ts +2 -2
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/popover.d.ts +1 -1
- package/lib/core/components/shadcn/popover.d.ts.map +1 -1
- package/lib/core/components/shadcn/popover.js.map +1 -1
- package/lib/core/components/shadcn/radioGroup.d.ts.map +1 -1
- package/lib/core/components/shadcn/selectBox.js +1 -1
- package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/core/components/shadcn/tabs.js +1 -1
- package/lib/core/components/shadcn/text.d.ts +2 -2
- package/lib/core/components/shadcn/theme/ThemeSwitcher.js.map +1 -1
- package/lib/core/components/toast/ToastProvider.js +1 -1
- package/lib/core/hooks/CompositeState.d.ts +1 -1
- package/lib/core/hooks/CompositeState.d.ts.map +1 -1
- package/lib/core/hooks/CompositeState.js.map +1 -1
- package/lib/core/hooks/SharedState.d.ts.map +1 -1
- package/lib/core/hooks/useFetch.d.ts.map +1 -1
- package/lib/core/hooks/useFetch.js +2 -1
- package/lib/core/hooks/useFetch.js.map +1 -1
- package/lib/core/hooks/useFlag.d.ts.map +1 -1
- package/lib/core/hooks/useIntersectionObserver.js.map +1 -1
- package/lib/core/hooks/useSafeLayoutEffect.d.ts +2 -2
- package/lib/core/hooks/useSafeLayoutEffect.d.ts.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/core/hooks/useSharedValue.d.ts.map +1 -1
- package/lib/core/hooks/useSharedValue.js.map +1 -1
- package/lib/core/utils/a11y.d.ts.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/PayloadBuilder.d.ts +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/PayloadBuilder.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/ArtifactsTab.js +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +1 -1
- package/lib/features/agent/chat/DocumentEditingActionCard.js +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +8 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +79 -20
- 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.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +25 -10
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +7 -0
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +40 -3
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts.map +1 -1
- 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/InlineSlidingPlanPanel.d.ts.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.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +8 -0
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +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/utils.d.ts.map +1 -1
- package/lib/features/agent/chat/SlidingThinkingIndicator.js +1 -1
- package/lib/features/agent/chat/VegaLiteChart.js +1 -1
- 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 +38 -3
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.d.ts +8 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useFileProcessing.js +31 -2
- package/lib/features/agent/chat/hooks/useFileProcessing.js.map +1 -1
- package/lib/features/agent/chat/index.d.ts +1 -1
- package/lib/features/agent/chat/index.d.ts.map +1 -1
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/agent/chat/useArtifactUrlCache.js.map +1 -1
- package/lib/features/agent/chat/workstreams.d.ts +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/InteractionsFacetsNav.d.ts.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/facets/RunsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
- package/lib/features/magic-pdf/GroundedExtractionView.js +1 -1
- package/lib/features/magic-pdf/MagicPdfProvider.d.ts.map +1 -1
- package/lib/features/magic-pdf/MagicPdfProvider.js.map +1 -1
- package/lib/features/oauth/McpConnectionsButton.js +1 -1
- package/lib/features/oauth/OAuthProviderConnectButton.js +1 -1
- package/lib/features/oauth/RemoteMcpConnectionButton.js +1 -1
- package/lib/features/pdf-viewer/PdfPageRenderer.js +1 -1
- package/lib/features/pdf-viewer/PdfPageSlider.js +1 -1
- package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
- package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
- package/lib/features/store/collections/CollectionsTable.js +2 -2
- package/lib/features/store/collections/CollectionsTable.js.map +1 -1
- package/lib/features/store/collections/CreateCollection.js +1 -1
- package/lib/features/store/collections/EditCollectionView.js +1 -1
- package/lib/features/store/objects/DocumentQuickFilter.js +1 -1
- package/lib/features/store/objects/DocumentSelectionProvider.d.ts.map +1 -1
- package/lib/features/store/objects/DocumentSelectionProvider.js.map +1 -1
- package/lib/features/store/objects/components/ContentDispositionButton.d.ts +2 -1
- package/lib/features/store/objects/components/ContentDispositionButton.d.ts.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +5 -2
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/DocumentEditingPanel.js +1 -1
- package/lib/features/store/objects/components/PropertiesEditorModal.js +1 -1
- package/lib/features/store/objects/components/TextEditorPanel.js +1 -1
- package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts +31 -3
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
- package/lib/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
- package/lib/features/store/objects/layout/documentLayout.js +1 -1
- package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts +129 -7
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.js.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/ObjectsActionContextClass.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContextClass.js.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/SelectionActions.js +1 -1
- package/lib/features/store/objects/selection/actions/ConfirmAction.js +1 -1
- package/lib/features/store/objects/selection/actions/DeleteObjectsAction.js +1 -1
- package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js +1 -1
- 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/useUploadHandler.d.ts.map +1 -1
- package/lib/features/store/types/ContentObjectTypesSearch.js +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 +6 -2
- 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 +1252 -2
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.js.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/features/user/UserInfo.js +1 -1
- package/lib/features/user/UserInfo.js.map +1 -1
- package/lib/features/utils/mimeType.d.ts.map +1 -1
- package/lib/features/utils/rendition.js.map +1 -1
- package/lib/features/utils/text.js.map +1 -1
- package/lib/i18n/locales/ar.json +27 -1
- package/lib/i18n/locales/de.json +27 -1
- package/lib/i18n/locales/en.json +30 -1
- package/lib/i18n/locales/es.json +27 -1
- package/lib/i18n/locales/fr.json +27 -1
- package/lib/i18n/locales/it.json +27 -1
- package/lib/i18n/locales/ja.json +27 -1
- package/lib/i18n/locales/ko.json +27 -1
- package/lib/i18n/locales/pt.json +27 -1
- package/lib/i18n/locales/ru.json +27 -1
- package/lib/i18n/locales/tr.json +27 -1
- package/lib/i18n/locales/zh-TW.json +27 -1
- package/lib/i18n/locales/zh.json +27 -1
- package/lib/i18n/rtl.d.ts +1 -1
- package/lib/i18n/rtl.d.ts.map +1 -1
- package/lib/layout/FullHeightLayout.d.ts +7 -6
- package/lib/layout/FullHeightLayout.d.ts.map +1 -1
- package/lib/layout/Sidebar.d.ts +1 -1
- package/lib/layout/Sidebar.js +1 -1
- package/lib/rich-text/EditorToolbar.js +1 -1
- package/lib/router/HistoryNavigator.d.ts +2 -2
- package/lib/router/HistoryNavigator.d.ts.map +1 -1
- package/lib/router/HistoryNavigator.js.map +1 -1
- package/lib/router/PathMatcher.d.ts.map +1 -1
- package/lib/router/PathMatcher.js.map +1 -1
- package/lib/router/PathWithParams.d.ts.map +1 -1
- package/lib/router/Redirect.js.map +1 -1
- package/lib/router/Route404.js +1 -1
- package/lib/router/Router.d.ts.map +1 -1
- package/lib/router/Router.js.map +1 -1
- package/lib/session/UserSession.d.ts +18 -4
- package/lib/session/UserSession.d.ts.map +1 -1
- package/lib/session/UserSession.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts +2 -0
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +81 -53
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts +49 -1
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +179 -53
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/shell/VertesiaShell.js +1 -1
- package/lib/shell/apps/AppInstallationProvider.d.ts +230 -2
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/apps/AppProjectSelector.js +1 -1
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/shell/login/SignInEmailStep.js +1 -1
- package/lib/shell/login/SignInPrimitives.d.ts +21 -20
- package/lib/shell/login/SignInPrimitives.d.ts.map +1 -1
- package/lib/shell/login/SignInPrimitives.js.map +1 -1
- package/lib/shell/login/SignInRecoveryStep.d.ts +22 -0
- package/lib/shell/login/SignInRecoveryStep.d.ts.map +1 -0
- package/lib/shell/login/SignInRecoveryStep.js +59 -0
- package/lib/shell/login/SignInRecoveryStep.js.map +1 -0
- package/lib/shell/login/SigninScreen.d.ts.map +1 -1
- package/lib/shell/login/SigninScreen.js +84 -11
- package/lib/shell/login/SigninScreen.js.map +1 -1
- package/lib/shell/login/SignupForm.js +1 -1
- package/lib/shell/login/TerminalLogin.js +1 -1
- package/lib/shell/login/UserSessionMenu.js +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +34 -34
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +13 -13
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js.map +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 +18 -18
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/form/FormContext.d.ts.map +1 -1
- package/lib/widgets/form/FormContext.js.map +1 -1
- package/lib/widgets/form/ManagedObject.d.ts +2 -2
- package/lib/widgets/form/ManagedObject.d.ts.map +1 -1
- package/lib/widgets/form/ManagedObject.js.map +1 -1
- package/lib/widgets/form/schema.d.ts.map +1 -1
- package/lib/widgets/form/schema.js.map +1 -1
- package/lib/widgets/json-view/JSONCode.js +1 -1
- package/lib/widgets/json-view/JSONTable.js +1 -1
- package/lib/widgets/markdown/ArtifactContentRenderer.js.map +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.d.ts +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.d.ts.map +1 -1
- package/lib/widgets/markdown/CodeBlockPlaceholder.js +1 -1
- package/lib/widgets/markdown/CodeBlockRendering.d.ts.map +1 -1
- package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +1 -1
- package/lib/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -1
- package/lib/widgets/markdown/textDiff.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/schema-editor/ManagedSchema.d.ts.map +1 -1
- package/lib/widgets/schema-editor/editor/PropertyEditor.js +1 -1
- package/lib/widgets/schema-editor/json-schema4-utils.js.map +1 -1
- package/lib/widgets/xml-viewer/components/Elements/index.js +1 -1
- package/lib/widgets/xml-viewer/components/Tag/index.js +1 -1
- package/lib/widgets/xml-viewer/constants/index.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/helpers/index.d.ts +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts.map +1 -1
- package/package.json +33 -33
- package/src/core/hooks/useFetch.ts +2 -1
- 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/ModernAgentConversation.test.tsx +208 -3
- package/src/features/agent/chat/ModernAgentConversation.tsx +130 -25
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +75 -20
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +112 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +62 -10
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +38 -0
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +62 -4
- 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 +18 -4
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +9 -0
- 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/utils.test.ts +21 -0
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +172 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +38 -3
- package/src/features/agent/chat/hooks/useFileProcessing.test.tsx +87 -0
- package/src/features/agent/chat/hooks/useFileProcessing.ts +32 -1
- package/src/features/agent/chat/index.ts +1 -0
- package/src/features/facets/PromptsFacetsNav.tsx +17 -9
- package/src/features/store/collections/CollectionsTable.tsx +1 -1
- package/src/features/store/objects/components/ContentOverview.tsx +4 -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/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 +27 -1
- package/src/i18n/locales/de.json +27 -1
- package/src/i18n/locales/en.json +30 -1
- package/src/i18n/locales/es.json +27 -1
- package/src/i18n/locales/fr.json +27 -1
- package/src/i18n/locales/it.json +27 -1
- package/src/i18n/locales/ja.json +27 -1
- package/src/i18n/locales/ko.json +27 -1
- package/src/i18n/locales/pt.json +27 -1
- package/src/i18n/locales/ru.json +27 -1
- package/src/i18n/locales/tr.json +27 -1
- package/src/i18n/locales/zh-TW.json +27 -1
- package/src/i18n/locales/zh.json +27 -1
- package/src/session/UserSessionProvider.test.ts +69 -0
- package/src/session/UserSessionProvider.tsx +96 -60
- package/src/session/auth/composable.scope.test.ts +88 -0
- package/src/session/auth/composable.test.ts +205 -0
- package/src/session/auth/composable.ts +227 -58
- package/src/shell/login/InviteAcceptModal.tsx +4 -4
- package/src/shell/login/SignInPrimitives.tsx +1 -0
- package/src/shell/login/SignInRecoveryStep.test.tsx +112 -0
- package/src/shell/login/SignInRecoveryStep.tsx +177 -0
- package/src/shell/login/SigninScreen.tsx +145 -27
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +13 -9
- package/src/widgets/monacoEditor/MonacoEditor.tsx +83 -7
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import SignInRecoveryStep from './SignInRecoveryStep';
|
|
4
|
+
|
|
5
|
+
const translations: Record<string, string> = {
|
|
6
|
+
'auth.recovery.scopeProject.eyebrow': 'Link Unavailable',
|
|
7
|
+
'auth.recovery.scopeProject.title': 'Project not available',
|
|
8
|
+
'auth.recovery.scopeProject.body':
|
|
9
|
+
'You’re signed in, but the project in this link isn’t available. The link may be outdated, or you may not have access.',
|
|
10
|
+
'auth.recovery.scopeAccount.eyebrow': 'Link Unavailable',
|
|
11
|
+
'auth.recovery.scopeAccount.title': 'Account not available',
|
|
12
|
+
'auth.recovery.scopeAccount.body': 'Account unavailable body',
|
|
13
|
+
'auth.recovery.noAccessibleAccount.eyebrow': 'Account Required',
|
|
14
|
+
'auth.recovery.noAccessibleAccount.title': 'No account is available',
|
|
15
|
+
'auth.recovery.noAccessibleAccount.body': 'No accessible account body',
|
|
16
|
+
'auth.recovery.credential.eyebrow': 'Sign-In Required',
|
|
17
|
+
'auth.recovery.credential.title': 'Your sign-in could not be verified',
|
|
18
|
+
'auth.recovery.credential.body': 'Credential body',
|
|
19
|
+
'auth.recovery.service.eyebrow': 'Service Unavailable',
|
|
20
|
+
'auth.recovery.service.title': "We couldn't complete sign-in",
|
|
21
|
+
'auth.recovery.service.body': 'Service body',
|
|
22
|
+
'auth.recovery.continue': 'Continue to Vertesia',
|
|
23
|
+
'auth.recovery.tryAgain': 'Try again',
|
|
24
|
+
'auth.recovery.useDifferentAccount': 'Use a different account',
|
|
25
|
+
'auth.recovery.supportPrefix': 'If you need help, contact',
|
|
26
|
+
'auth.recovery.technicalDetails': 'Technical details',
|
|
27
|
+
'auth.recovery.errorCode': 'Error code',
|
|
28
|
+
'auth.recovery.httpStatus': 'HTTP status',
|
|
29
|
+
'auth.recovery.requestedAccount': 'Requested account',
|
|
30
|
+
'auth.recovery.requestedProject': 'Requested project',
|
|
31
|
+
'auth.recovery.errorMessage': 'Error message',
|
|
32
|
+
'auth.returning.notYou': 'Not you?',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
vi.mock('@vertesia/ui/i18n', () => ({
|
|
36
|
+
useUITranslation: () => ({ t: (key: string) => translations[key] ?? key }),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
describe('SignInRecoveryStep', () => {
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
document.body.innerHTML = '';
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('shows project-safe copy, focuses the primary action, and prevents duplicate submissions', () => {
|
|
45
|
+
const onContinue = vi.fn();
|
|
46
|
+
render(<SignInRecoveryStep kind="scopeProject" onContinue={onContinue} onUseDifferentAccount={vi.fn()} />);
|
|
47
|
+
|
|
48
|
+
expect(screen.getByText('Project not available')).toBeTruthy();
|
|
49
|
+
expect(screen.getByText(/project in this link isn’t available/)).toBeTruthy();
|
|
50
|
+
const continueButton = screen.getByRole('button', { name: 'Continue to Vertesia' });
|
|
51
|
+
expect(document.activeElement).toBe(continueButton);
|
|
52
|
+
|
|
53
|
+
fireEvent.click(continueButton);
|
|
54
|
+
fireEvent.click(continueButton);
|
|
55
|
+
|
|
56
|
+
expect(onContinue).toHaveBeenCalledOnce();
|
|
57
|
+
expect((continueButton as HTMLButtonElement).disabled).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('omits continue for an identity with no accessible account and includes support guidance', () => {
|
|
61
|
+
const onUseDifferentAccount = vi.fn();
|
|
62
|
+
render(<SignInRecoveryStep kind="noAccessibleAccount" onUseDifferentAccount={onUseDifferentAccount} />);
|
|
63
|
+
|
|
64
|
+
expect(screen.queryByRole('button', { name: 'Continue to Vertesia' })).toBeNull();
|
|
65
|
+
expect(screen.getByText('No account is available')).toBeTruthy();
|
|
66
|
+
expect(screen.getByRole('link', { name: 'support@vertesiahq.com' }).getAttribute('href')).toBe(
|
|
67
|
+
'mailto:support@vertesiahq.com',
|
|
68
|
+
);
|
|
69
|
+
expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Use a different account' }));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('shows submitted selectors and the normalized server error in collapsed technical details', () => {
|
|
73
|
+
render(
|
|
74
|
+
<SignInRecoveryStep
|
|
75
|
+
details={{
|
|
76
|
+
accountId: 'apple',
|
|
77
|
+
errorCode: 'requested_scope_unavailable',
|
|
78
|
+
message: 'The requested account or project is not available.',
|
|
79
|
+
projectId: 'banana',
|
|
80
|
+
status: 403,
|
|
81
|
+
}}
|
|
82
|
+
kind="scopeProject"
|
|
83
|
+
onContinue={vi.fn()}
|
|
84
|
+
onUseDifferentAccount={vi.fn()}
|
|
85
|
+
/>,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const disclosure = screen.getByText('Technical details').closest('details');
|
|
89
|
+
expect(disclosure?.hasAttribute('open')).toBe(false);
|
|
90
|
+
expect(screen.getByText('requested_scope_unavailable')).toBeTruthy();
|
|
91
|
+
expect(screen.getByText('apple')).toBeTruthy();
|
|
92
|
+
expect(screen.getByText('banana')).toBeTruthy();
|
|
93
|
+
expect(screen.getByText('The requested account or project is not available.')).toBeTruthy();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('reuses the returning-user identity row for the authenticated credential', () => {
|
|
97
|
+
const onUseDifferentAccount = vi.fn();
|
|
98
|
+
render(
|
|
99
|
+
<SignInRecoveryStep
|
|
100
|
+
identity={{ email: 'leon@example.com', name: 'Leon Ruggiero' }}
|
|
101
|
+
kind="scopeProject"
|
|
102
|
+
onContinue={vi.fn()}
|
|
103
|
+
onUseDifferentAccount={onUseDifferentAccount}
|
|
104
|
+
/>,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
expect(screen.getByText('Leon Ruggiero')).toBeTruthy();
|
|
108
|
+
expect(screen.getByText('leon@example.com')).toBeTruthy();
|
|
109
|
+
fireEvent.click(screen.getByRole('button', { name: 'Not you?' }));
|
|
110
|
+
expect(onUseDifferentAccount).toHaveBeenCalledOnce();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
2
|
+
import { AlertTriangle } from 'lucide-react';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import {
|
|
5
|
+
SignInAccountRow,
|
|
6
|
+
SignInIconBadge,
|
|
7
|
+
SignInInitialsBadge,
|
|
8
|
+
SignInStepButton,
|
|
9
|
+
SignInStepHeader,
|
|
10
|
+
SignInStepLayout,
|
|
11
|
+
} from './SignInPrimitives';
|
|
12
|
+
import { emailInitial, firstNameFromEmail } from './signInUtils';
|
|
13
|
+
|
|
14
|
+
export type SignInRecoveryKind = 'scopeProject' | 'scopeAccount' | 'noAccessibleAccount' | 'credential' | 'service';
|
|
15
|
+
|
|
16
|
+
export interface SignInRecoveryDetails {
|
|
17
|
+
accountId?: string;
|
|
18
|
+
errorCode?: string;
|
|
19
|
+
message: string;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
status?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SignInRecoveryIdentity {
|
|
25
|
+
email: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface SignInRecoveryStepProps {
|
|
30
|
+
details?: SignInRecoveryDetails;
|
|
31
|
+
identity?: SignInRecoveryIdentity;
|
|
32
|
+
kind: SignInRecoveryKind;
|
|
33
|
+
onContinue?: () => void;
|
|
34
|
+
onUseDifferentAccount: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function SignInRecoveryStep({
|
|
38
|
+
details,
|
|
39
|
+
identity,
|
|
40
|
+
kind,
|
|
41
|
+
onContinue,
|
|
42
|
+
onUseDifferentAccount,
|
|
43
|
+
}: SignInRecoveryStepProps) {
|
|
44
|
+
const { t } = useUITranslation();
|
|
45
|
+
const [submitting, setSubmitting] = useState(false);
|
|
46
|
+
const initialButtonRef = useRef<HTMLButtonElement>(null);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
initialButtonRef.current?.focus();
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const isScopeFailure = kind === 'scopeProject' || kind === 'scopeAccount';
|
|
53
|
+
let copy: { eyebrow: string; title: string; body: string };
|
|
54
|
+
if (kind === 'scopeProject') {
|
|
55
|
+
copy = {
|
|
56
|
+
eyebrow: t('auth.recovery.scopeProject.eyebrow'),
|
|
57
|
+
title: t('auth.recovery.scopeProject.title'),
|
|
58
|
+
body: t('auth.recovery.scopeProject.body'),
|
|
59
|
+
};
|
|
60
|
+
} else if (kind === 'scopeAccount') {
|
|
61
|
+
copy = {
|
|
62
|
+
eyebrow: t('auth.recovery.scopeAccount.eyebrow'),
|
|
63
|
+
title: t('auth.recovery.scopeAccount.title'),
|
|
64
|
+
body: t('auth.recovery.scopeAccount.body'),
|
|
65
|
+
};
|
|
66
|
+
} else if (kind === 'noAccessibleAccount') {
|
|
67
|
+
copy = {
|
|
68
|
+
eyebrow: t('auth.recovery.noAccessibleAccount.eyebrow'),
|
|
69
|
+
title: t('auth.recovery.noAccessibleAccount.title'),
|
|
70
|
+
body: t('auth.recovery.noAccessibleAccount.body'),
|
|
71
|
+
};
|
|
72
|
+
} else if (kind === 'credential') {
|
|
73
|
+
copy = {
|
|
74
|
+
eyebrow: t('auth.recovery.credential.eyebrow'),
|
|
75
|
+
title: t('auth.recovery.credential.title'),
|
|
76
|
+
body: t('auth.recovery.credential.body'),
|
|
77
|
+
};
|
|
78
|
+
} else {
|
|
79
|
+
copy = {
|
|
80
|
+
eyebrow: t('auth.recovery.service.eyebrow'),
|
|
81
|
+
title: t('auth.recovery.service.title'),
|
|
82
|
+
body: t('auth.recovery.service.body'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const runAction = (action: () => void) => {
|
|
87
|
+
if (submitting) return;
|
|
88
|
+
setSubmitting(true);
|
|
89
|
+
action();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<SignInStepLayout>
|
|
94
|
+
<div role="alert" aria-live="assertive">
|
|
95
|
+
<SignInIconBadge>
|
|
96
|
+
<AlertTriangle className="size-7 text-attention" aria-hidden="true" />
|
|
97
|
+
</SignInIconBadge>
|
|
98
|
+
<SignInStepHeader eyebrow={copy.eyebrow} title={copy.title} body={copy.body} />
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{identity && (
|
|
102
|
+
<SignInAccountRow
|
|
103
|
+
badge={<SignInInitialsBadge initials={emailInitial(identity.email)} />}
|
|
104
|
+
title={identity.name || firstNameFromEmail(identity.email)}
|
|
105
|
+
subtitle={identity.email}
|
|
106
|
+
actionLabel={t('auth.returning.notYou')}
|
|
107
|
+
onAction={onUseDifferentAccount}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
110
|
+
|
|
111
|
+
<div className="flex flex-col gap-2">
|
|
112
|
+
{onContinue && (
|
|
113
|
+
<SignInStepButton
|
|
114
|
+
ref={initialButtonRef}
|
|
115
|
+
className="w-full"
|
|
116
|
+
disabled={submitting}
|
|
117
|
+
onClick={() => runAction(onContinue)}
|
|
118
|
+
>
|
|
119
|
+
{isScopeFailure ? t('auth.recovery.continue') : t('auth.recovery.tryAgain')}
|
|
120
|
+
</SignInStepButton>
|
|
121
|
+
)}
|
|
122
|
+
<SignInStepButton
|
|
123
|
+
ref={onContinue ? undefined : initialButtonRef}
|
|
124
|
+
variant={onContinue ? 'ghost' : 'primary'}
|
|
125
|
+
disabled={submitting}
|
|
126
|
+
onClick={() => runAction(onUseDifferentAccount)}
|
|
127
|
+
>
|
|
128
|
+
{t('auth.recovery.useDifferentAccount')}
|
|
129
|
+
</SignInStepButton>
|
|
130
|
+
{(kind === 'noAccessibleAccount' || kind === 'service') && (
|
|
131
|
+
<p className="text-center text-xs text-muted">
|
|
132
|
+
{t('auth.recovery.supportPrefix')}{' '}
|
|
133
|
+
<a className="text-info" href="mailto:support@vertesiahq.com">
|
|
134
|
+
support@vertesiahq.com
|
|
135
|
+
</a>
|
|
136
|
+
</p>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
{details && (
|
|
141
|
+
<details className="rounded-lg border border-mixer-muted/30 bg-mixer-muted/10 px-4 py-3 text-sm">
|
|
142
|
+
<summary className="cursor-pointer font-medium text-muted marker:text-muted focus-visible:outline-2 focus-visible:outline-offset-2">
|
|
143
|
+
{t('auth.recovery.technicalDetails')}
|
|
144
|
+
</summary>
|
|
145
|
+
<dl className="mt-3 grid grid-cols-[max-content_minmax(0,1fr)] gap-x-3 gap-y-2 text-xs">
|
|
146
|
+
{details.errorCode && (
|
|
147
|
+
<>
|
|
148
|
+
<dt className="text-muted">{t('auth.recovery.errorCode')}</dt>
|
|
149
|
+
<dd className="wrap-break-word font-mono">{details.errorCode}</dd>
|
|
150
|
+
</>
|
|
151
|
+
)}
|
|
152
|
+
{details.status && (
|
|
153
|
+
<>
|
|
154
|
+
<dt className="text-muted">{t('auth.recovery.httpStatus')}</dt>
|
|
155
|
+
<dd className="font-mono">{details.status}</dd>
|
|
156
|
+
</>
|
|
157
|
+
)}
|
|
158
|
+
{details.accountId && (
|
|
159
|
+
<>
|
|
160
|
+
<dt className="text-muted">{t('auth.recovery.requestedAccount')}</dt>
|
|
161
|
+
<dd className="wrap-break-word font-mono">{details.accountId}</dd>
|
|
162
|
+
</>
|
|
163
|
+
)}
|
|
164
|
+
{details.projectId && (
|
|
165
|
+
<>
|
|
166
|
+
<dt className="text-muted">{t('auth.recovery.requestedProject')}</dt>
|
|
167
|
+
<dd className="wrap-break-word font-mono">{details.projectId}</dd>
|
|
168
|
+
</>
|
|
169
|
+
)}
|
|
170
|
+
<dt className="text-muted">{t('auth.recovery.errorMessage')}</dt>
|
|
171
|
+
<dd className="wrap-break-word font-mono">{details.message}</dd>
|
|
172
|
+
</dl>
|
|
173
|
+
</details>
|
|
174
|
+
)}
|
|
175
|
+
</SignInStepLayout>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE, type SignupData, type SignupPayload } from '@vertesia/common';
|
|
2
2
|
import { Env } from '@vertesia/ui/env';
|
|
3
3
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
4
4
|
import { RegionTag } from '@vertesia/ui/layout';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AuthenticationServiceError,
|
|
7
|
+
CredentialError,
|
|
8
|
+
NoAccessibleAccountError,
|
|
9
|
+
RequestedScopeUnavailableError,
|
|
10
|
+
RestrictedEnvironmentError,
|
|
11
|
+
UserNotFoundError,
|
|
12
|
+
useUserSession,
|
|
13
|
+
useUXTracking,
|
|
14
|
+
} from '@vertesia/ui/session';
|
|
6
15
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
16
|
import SignInAuthPending from './SignInAuthPending';
|
|
8
17
|
import SignInEmailStep, { type TenantInfo } from './SignInEmailStep';
|
|
9
18
|
import SignInProvidersStep from './SignInProvidersStep';
|
|
19
|
+
import SignInRecoveryStep, { type SignInRecoveryKind } from './SignInRecoveryStep';
|
|
10
20
|
import SignInRestrictedEnvStep from './SignInRestrictedEnvStep';
|
|
11
21
|
import SignInReturningStep from './SignInReturningStep';
|
|
12
22
|
import SignInTenantBlockedStep from './SignInTenantBlockedStep';
|
|
@@ -65,7 +75,30 @@ function matchesPathPrefix(pathname: string, prefix?: string | string[]) {
|
|
|
65
75
|
});
|
|
66
76
|
}
|
|
67
77
|
|
|
68
|
-
type Mode =
|
|
78
|
+
type Mode =
|
|
79
|
+
| 'email'
|
|
80
|
+
| 'providers'
|
|
81
|
+
| 'tenant'
|
|
82
|
+
| 'blocked'
|
|
83
|
+
| 'returning'
|
|
84
|
+
| 'pending'
|
|
85
|
+
| 'signup'
|
|
86
|
+
| 'restricted'
|
|
87
|
+
| 'scopeUnavailable'
|
|
88
|
+
| 'noAccessibleAccount'
|
|
89
|
+
| 'credentialFailure'
|
|
90
|
+
| 'serviceFailure';
|
|
91
|
+
|
|
92
|
+
function isDedicatedAuthError(error: Error): boolean {
|
|
93
|
+
return (
|
|
94
|
+
error instanceof UserNotFoundError ||
|
|
95
|
+
error instanceof RestrictedEnvironmentError ||
|
|
96
|
+
error instanceof RequestedScopeUnavailableError ||
|
|
97
|
+
error instanceof NoAccessibleAccountError ||
|
|
98
|
+
error instanceof CredentialError ||
|
|
99
|
+
error instanceof AuthenticationServiceError
|
|
100
|
+
);
|
|
101
|
+
}
|
|
69
102
|
|
|
70
103
|
function SigninScreenImpl({
|
|
71
104
|
isNested = false,
|
|
@@ -87,8 +120,20 @@ function SigninScreenImpl({
|
|
|
87
120
|
const [tenant, setTenant] = useState<TenantInfo | undefined>(undefined);
|
|
88
121
|
const [pendingProvider, setPendingProvider] = useState<ProviderId | null>(null);
|
|
89
122
|
|
|
123
|
+
const recoveryIdentity =
|
|
124
|
+
authError instanceof RequestedScopeUnavailableError || authError instanceof NoAccessibleAccountError
|
|
125
|
+
? authError.identity
|
|
126
|
+
: undefined;
|
|
127
|
+
const matchingStoredIdentity =
|
|
128
|
+
recoveryIdentity && storedSession?.email.toLowerCase() === recoveryIdentity.email.toLowerCase()
|
|
129
|
+
? storedSession
|
|
130
|
+
: undefined;
|
|
131
|
+
const displayedRecoveryIdentity = recoveryIdentity
|
|
132
|
+
? { email: recoveryIdentity.email, name: recoveryIdentity.name ?? matchingStoredIdentity?.name }
|
|
133
|
+
: undefined;
|
|
134
|
+
|
|
90
135
|
useEffect(() => {
|
|
91
|
-
if (!preservePath) {
|
|
136
|
+
if (!preservePath && !isLoading && !authError) {
|
|
92
137
|
// Reset to the app's mount root, not the bare origin. A gateway-mounted app carries a
|
|
93
138
|
// served `<base href>` deep mount; collapsing to '/' drops the app off that mount (the
|
|
94
139
|
// bare origin serves no app) and the address bar can no longer be reloaded. This effect
|
|
@@ -99,7 +144,7 @@ function SigninScreenImpl({
|
|
|
99
144
|
const mountRoot = new URL(document.baseURI).pathname || '/';
|
|
100
145
|
history.replaceState({}, '', mountRoot);
|
|
101
146
|
}
|
|
102
|
-
}, [preservePath]);
|
|
147
|
+
}, [authError, isLoading, preservePath]);
|
|
103
148
|
|
|
104
149
|
// Route based on authError surfaced by the session.
|
|
105
150
|
useEffect(() => {
|
|
@@ -108,6 +153,14 @@ function SigninScreenImpl({
|
|
|
108
153
|
setMode('signup');
|
|
109
154
|
} else if (authError instanceof RestrictedEnvironmentError) {
|
|
110
155
|
setMode('restricted');
|
|
156
|
+
} else if (authError instanceof RequestedScopeUnavailableError) {
|
|
157
|
+
setMode('scopeUnavailable');
|
|
158
|
+
} else if (authError instanceof NoAccessibleAccountError) {
|
|
159
|
+
setMode('noAccessibleAccount');
|
|
160
|
+
} else if (authError instanceof CredentialError) {
|
|
161
|
+
setMode('credentialFailure');
|
|
162
|
+
} else if (authError instanceof AuthenticationServiceError) {
|
|
163
|
+
setMode('serviceFailure');
|
|
111
164
|
} else if (isInviteRequiredError(authError)) {
|
|
112
165
|
const pending = readPendingSignin();
|
|
113
166
|
if (pending) setEmail(pending.email);
|
|
@@ -176,6 +229,37 @@ function SigninScreenImpl({
|
|
|
176
229
|
void resetSignInState();
|
|
177
230
|
}, []);
|
|
178
231
|
|
|
232
|
+
const useDifferentAccount = useCallback(() => {
|
|
233
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
234
|
+
vertesia: { recovery_action: 'use_different_account' },
|
|
235
|
+
});
|
|
236
|
+
setStoredSession(null);
|
|
237
|
+
setEmail('');
|
|
238
|
+
setTenant(undefined);
|
|
239
|
+
setMode('email');
|
|
240
|
+
void resetSignInState().finally(() => signOut());
|
|
241
|
+
}, [signOut]);
|
|
242
|
+
|
|
243
|
+
const continueWithSanitizedScope = useCallback(() => {
|
|
244
|
+
if (!(authError instanceof RequestedScopeUnavailableError)) return;
|
|
245
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
246
|
+
vertesia: {
|
|
247
|
+
error_code: REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE,
|
|
248
|
+
selector_source: authError.selectorSource,
|
|
249
|
+
requested_scope: authError.requestedScope,
|
|
250
|
+
recovery_action: 'continue_sanitized',
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
window.location.replace(authError.recoveryUrl ?? window.location.href);
|
|
254
|
+
}, [authError]);
|
|
255
|
+
|
|
256
|
+
const retryAuthentication = useCallback(() => {
|
|
257
|
+
Env.logger.info('Authentication recovery action selected', {
|
|
258
|
+
vertesia: { recovery_action: 'retry' },
|
|
259
|
+
});
|
|
260
|
+
window.location.reload();
|
|
261
|
+
}, []);
|
|
262
|
+
|
|
179
263
|
// Submits the signup form to /auth/signup, then redirects into the app.
|
|
180
264
|
const onSignup = (data: SignupData, fbToken: string) => {
|
|
181
265
|
const payload: SignupPayload = { signupData: data, firebaseToken: fbToken };
|
|
@@ -190,10 +274,7 @@ function SigninScreenImpl({
|
|
|
190
274
|
};
|
|
191
275
|
|
|
192
276
|
const shouldHideTransientAuthError =
|
|
193
|
-
suppressAuthError &&
|
|
194
|
-
authError !== undefined &&
|
|
195
|
-
!(authError instanceof UserNotFoundError) &&
|
|
196
|
-
!(authError instanceof RestrictedEnvironmentError);
|
|
277
|
+
suppressAuthError && authError !== undefined && !isDedicatedAuthError(authError);
|
|
197
278
|
|
|
198
279
|
if (isLoading || user || shouldHideTransientAuthError) return null;
|
|
199
280
|
|
|
@@ -210,6 +291,49 @@ function SigninScreenImpl({
|
|
|
210
291
|
);
|
|
211
292
|
} else if (mode === 'restricted') {
|
|
212
293
|
content = <SignInRestrictedEnvStep onUseDifferentEmail={startOver} />;
|
|
294
|
+
} else if (mode === 'scopeUnavailable' && authError instanceof RequestedScopeUnavailableError) {
|
|
295
|
+
const kind: SignInRecoveryKind = authError.requestedScope === 'project' ? 'scopeProject' : 'scopeAccount';
|
|
296
|
+
content = (
|
|
297
|
+
<SignInRecoveryStep
|
|
298
|
+
details={{
|
|
299
|
+
accountId: authError.accountId,
|
|
300
|
+
errorCode: authError.errorCode,
|
|
301
|
+
message: authError.message,
|
|
302
|
+
projectId: authError.projectId,
|
|
303
|
+
status: authError.status,
|
|
304
|
+
}}
|
|
305
|
+
identity={displayedRecoveryIdentity}
|
|
306
|
+
kind={kind}
|
|
307
|
+
onContinue={continueWithSanitizedScope}
|
|
308
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
309
|
+
/>
|
|
310
|
+
);
|
|
311
|
+
} else if (mode === 'noAccessibleAccount' && authError instanceof NoAccessibleAccountError) {
|
|
312
|
+
content = (
|
|
313
|
+
<SignInRecoveryStep
|
|
314
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
315
|
+
identity={displayedRecoveryIdentity}
|
|
316
|
+
kind="noAccessibleAccount"
|
|
317
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
318
|
+
/>
|
|
319
|
+
);
|
|
320
|
+
} else if (mode === 'credentialFailure' && authError instanceof CredentialError) {
|
|
321
|
+
content = (
|
|
322
|
+
<SignInRecoveryStep
|
|
323
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
324
|
+
kind="credential"
|
|
325
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
326
|
+
/>
|
|
327
|
+
);
|
|
328
|
+
} else if (mode === 'serviceFailure' && authError instanceof AuthenticationServiceError) {
|
|
329
|
+
content = (
|
|
330
|
+
<SignInRecoveryStep
|
|
331
|
+
details={{ errorCode: authError.errorCode, message: authError.message, status: authError.status }}
|
|
332
|
+
kind="service"
|
|
333
|
+
onContinue={retryAuthentication}
|
|
334
|
+
onUseDifferentAccount={useDifferentAccount}
|
|
335
|
+
/>
|
|
336
|
+
);
|
|
213
337
|
} else if (mode === 'signup' && !localStorage.getItem('tenantName')) {
|
|
214
338
|
content = <SignupForm onSignup={onSignup} goBack={startOver} />;
|
|
215
339
|
} else if (mode === 'tenant' && tenant) {
|
|
@@ -247,25 +371,19 @@ function SigninScreenImpl({
|
|
|
247
371
|
|
|
248
372
|
{content}
|
|
249
373
|
|
|
250
|
-
{authError &&
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
support@vertesiahq.com
|
|
261
|
-
</a>
|
|
262
|
-
{t('auth.signInErrorPersists')}
|
|
263
|
-
<pre className="mt-2 text-xs">
|
|
264
|
-
{t('auth.error', { message: authError.message })}
|
|
265
|
-
</pre>
|
|
266
|
-
</div>
|
|
374
|
+
{authError && !isDedicatedAuthError(authError) && !isInviteRequiredError(authError) && (
|
|
375
|
+
<div className="mt-6 max-w-[420px] text-center text-sm text-muted">
|
|
376
|
+
<div>
|
|
377
|
+
{t('auth.signInError')}
|
|
378
|
+
<br />
|
|
379
|
+
{t('auth.signInErrorContact')}
|
|
380
|
+
<a className="text-info mx-1" href="mailto:support@vertesiahq.com">
|
|
381
|
+
support@vertesiahq.com
|
|
382
|
+
</a>
|
|
383
|
+
{t('auth.signInErrorPersists')}
|
|
267
384
|
</div>
|
|
268
|
-
|
|
385
|
+
</div>
|
|
386
|
+
)}
|
|
269
387
|
|
|
270
388
|
<div className="flex items-center gap-5 mt-10 text-xs text-muted-foreground">
|
|
271
389
|
<a href="https://vertesiahq.com/privacy" className="hover:text-foreground transition">
|
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
} from './ArtifactEditingSurface.js';
|
|
14
14
|
import type { MarkdownEditingAction } from './CollaborativeMarkdownRenderer.js';
|
|
15
15
|
|
|
16
|
+
// Document mode is loaded through React.lazy(). CI transforms many test files concurrently, so the
|
|
17
|
+
// first document-mode test can legitimately take longer than Testing Library's one-second default.
|
|
18
|
+
const LAZY_EDITOR_WAIT = { timeout: 5_000 } as const;
|
|
19
|
+
|
|
16
20
|
const mocks = vi.hoisted(() => {
|
|
17
21
|
const getArtifactContent = vi.fn();
|
|
18
22
|
const updateArtifactContent = vi.fn();
|
|
@@ -151,7 +155,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
151
155
|
const user = userEvent.setup();
|
|
152
156
|
renderSurface({ viewMode: 'document' });
|
|
153
157
|
|
|
154
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
158
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
155
159
|
await user.click(editor);
|
|
156
160
|
await user.type(editor, ' revised');
|
|
157
161
|
|
|
@@ -174,7 +178,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
174
178
|
onSendMessage: vi.fn(),
|
|
175
179
|
});
|
|
176
180
|
|
|
177
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
181
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
178
182
|
expect(editor.getAttribute('contenteditable')).toBe('false');
|
|
179
183
|
expect(screen.queryByRole('button', { name: 'Comment on selection' })).toBeNull();
|
|
180
184
|
});
|
|
@@ -188,7 +192,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
188
192
|
toolbarStatus: <span>AI is editing</span>,
|
|
189
193
|
});
|
|
190
194
|
|
|
191
|
-
const button = await screen.findByRole('button', { name: 'Send changes to agent' });
|
|
195
|
+
const button = await screen.findByRole('button', { name: 'Send changes to agent' }, LAZY_EDITOR_WAIT);
|
|
192
196
|
expect(screen.getByRole('toolbar').contains(button)).toBe(true);
|
|
193
197
|
expect(button.previousElementSibling?.textContent).toBe('AI is editing');
|
|
194
198
|
expect(button).toHaveProperty('disabled', false);
|
|
@@ -203,7 +207,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
203
207
|
> = { current: null };
|
|
204
208
|
renderSurface({ viewMode: 'document', flushChangesRef });
|
|
205
209
|
|
|
206
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
210
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
207
211
|
await user.click(editor);
|
|
208
212
|
await user.type(editor, ' immediate');
|
|
209
213
|
|
|
@@ -228,7 +232,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
228
232
|
});
|
|
229
233
|
const view = renderSurface({ viewMode: 'document' });
|
|
230
234
|
|
|
231
|
-
fireEvent.click(await screen.findByRole('button', { name: 'Edit Markdown source' }));
|
|
235
|
+
fireEvent.click(await screen.findByRole('button', { name: 'Edit Markdown source' }, LAZY_EDITOR_WAIT));
|
|
232
236
|
const sourceEditor = screen.getByRole('textbox', { name: 'Markdown source editor' });
|
|
233
237
|
fireEvent.focus(sourceEditor);
|
|
234
238
|
fireEvent.change(sourceEditor, {
|
|
@@ -249,7 +253,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
249
253
|
it('shows a navigable ruler for changes from the original document', async () => {
|
|
250
254
|
renderSurface({ viewMode: 'document', baselineContent: 'Different paragraph.' });
|
|
251
255
|
|
|
252
|
-
await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
256
|
+
await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
253
257
|
expect(screen.getByRole('navigation', { name: 'Change ruler' })).not.toBeNull();
|
|
254
258
|
expect(screen.getByRole('button', { name: 'Change near line 1' })).not.toBeNull();
|
|
255
259
|
});
|
|
@@ -257,7 +261,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
257
261
|
it('keeps the focused editor base generation when the agent refreshes the artifact', async () => {
|
|
258
262
|
const user = userEvent.setup();
|
|
259
263
|
const view = renderSurface({ viewMode: 'document' });
|
|
260
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
264
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
261
265
|
await user.click(editor);
|
|
262
266
|
|
|
263
267
|
mocks.getArtifactContent.mockResolvedValueOnce({
|
|
@@ -311,7 +315,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
311
315
|
.mockResolvedValueOnce({ path: 'drafts/document.md', generation: 'generation-merged' });
|
|
312
316
|
|
|
313
317
|
const view = renderSurface({ viewMode: 'document' });
|
|
314
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
318
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
315
319
|
await user.click(editor);
|
|
316
320
|
|
|
317
321
|
view.rerender(
|
|
@@ -363,7 +367,7 @@ describe('ArtifactEditingSurface', () => {
|
|
|
363
367
|
mocks.updateArtifactContent.mockRejectedValueOnce({ status: 412 });
|
|
364
368
|
renderSurface({ viewMode: 'document' });
|
|
365
369
|
|
|
366
|
-
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' });
|
|
370
|
+
const editor = await screen.findByRole('textbox', { name: 'Markdown document editor' }, LAZY_EDITOR_WAIT);
|
|
367
371
|
await user.click(editor);
|
|
368
372
|
await user.type(editor, ' local edit');
|
|
369
373
|
|