@vertesia/ui 1.5.0-dev.20260905.011013Z → 1.5.0-dev.20260910.052912Z
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/Avatar.d.ts.map +1 -1
- package/lib/core/components/Avatar.js +3 -3
- package/lib/core/components/Avatar.js.map +1 -1
- package/lib/core/components/ComboBox.js +1 -1
- package/lib/core/components/ComboBox.js.map +1 -1
- package/lib/core/components/FileUpload.js +1 -1
- package/lib/core/components/FileUpload.js.map +1 -1
- package/lib/core/components/Link.js +1 -1
- package/lib/core/components/Link.js.map +1 -1
- package/lib/core/components/SelectList.js +1 -1
- package/lib/core/components/SelectList.js.map +1 -1
- package/lib/core/components/SidePanel.js +1 -1
- package/lib/core/components/SidePanel.js.map +1 -1
- package/lib/core/components/Spinner.js +1 -1
- package/lib/core/components/Spinner.js.map +1 -1
- package/lib/core/components/TagsInput.js +8 -8
- package/lib/core/components/TagsInput.js.map +1 -1
- package/lib/core/components/shadcn/MessageBox.js +1 -1
- package/lib/core/components/shadcn/MessageBox.js.map +1 -1
- package/lib/core/components/shadcn/button.js +1 -1
- package/lib/core/components/shadcn/button.js.map +1 -1
- package/lib/core/components/shadcn/card.d.ts.map +1 -1
- package/lib/core/components/shadcn/card.js +1 -1
- package/lib/core/components/shadcn/card.js.map +1 -1
- package/lib/core/components/shadcn/command.js +5 -5
- package/lib/core/components/shadcn/command.js.map +1 -1
- package/lib/core/components/shadcn/filters/DynamicLabel.js +1 -1
- package/lib/core/components/shadcn/filters/DynamicLabel.js.map +1 -1
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +3 -3
- package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -1
- package/lib/core/components/shadcn/input.js +3 -3
- package/lib/core/components/shadcn/input.js.map +1 -1
- package/lib/core/components/shadcn/modal/ConfirmModal.js +1 -1
- package/lib/core/components/shadcn/modal/ConfirmModal.js.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
- package/lib/core/components/shadcn/modal/dialog.js +2 -2
- package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
- package/lib/core/components/shadcn/overflowTabs.js +2 -2
- package/lib/core/components/shadcn/overflowTabs.js.map +1 -1
- package/lib/core/components/shadcn/popover.js +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/radioGroup.js +3 -3
- package/lib/core/components/shadcn/radioGroup.js.map +1 -1
- package/lib/core/components/shadcn/selectBox.js +1 -1
- package/lib/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/core/components/shadcn/tabs.js +5 -2
- package/lib/core/components/shadcn/tabs.js.map +1 -1
- package/lib/core/components/styles.js +1 -1
- package/lib/core/components/styles.js.map +1 -1
- package/lib/core/components/table/index.js +1 -1
- package/lib/core/hooks/useFetch.d.ts.map +1 -1
- package/lib/core/hooks/useFetch.js +2 -0
- package/lib/core/hooks/useFetch.js.map +1 -1
- package/lib/features/activity-doc/ActivityDoc.js +8 -8
- package/lib/features/activity-doc/ActivityDoc.js.map +1 -1
- package/lib/features/agent/chat/AgentChart.js +1 -1
- package/lib/features/agent/chat/AgentChart.js.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +13 -13
- package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/features/agent/chat/JumpingDots.js +1 -1
- package/lib/features/agent/chat/JumpingDots.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +22 -9
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +5 -5
- package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +1 -1
- 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 +7 -7
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessagesContainer.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessagesContainer.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.js +10 -10
- package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +17 -17
- package/lib/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +14 -2
- 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 +15 -15
- package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +18 -0
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
- package/lib/features/agent/chat/SlidingThinkingIndicator.d.ts.map +1 -1
- package/lib/features/agent/chat/SlidingThinkingIndicator.js +5 -2
- package/lib/features/agent/chat/SlidingThinkingIndicator.js.map +1 -1
- package/lib/features/agent/chat/VegaLiteChart.d.ts.map +1 -1
- package/lib/features/agent/chat/VegaLiteChart.js +6 -2
- package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
- package/lib/features/errors/RowErrorBoundary.js +1 -1
- package/lib/features/errors/RowErrorBoundary.js.map +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.js +1 -1
- package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
- package/lib/features/facets/utils/VInteractionFacet.d.ts +3 -5
- package/lib/features/facets/utils/VInteractionFacet.d.ts.map +1 -1
- package/lib/features/facets/utils/VInteractionFacet.js +10 -23
- package/lib/features/facets/utils/VInteractionFacet.js.map +1 -1
- package/lib/features/facets/utils/VUserFacet.js +1 -1
- package/lib/features/facets/utils/VUserFacet.js.map +1 -1
- package/lib/features/layout/GenericPageNavHeader.d.ts.map +1 -1
- package/lib/features/layout/GenericPageNavHeader.js +4 -1
- package/lib/features/layout/GenericPageNavHeader.js.map +1 -1
- package/lib/features/layout/NotFoundView.js +1 -1
- package/lib/features/layout/NotFoundView.js.map +1 -1
- package/lib/features/magic-pdf/AnnotatedImageSlider.js +4 -12
- package/lib/features/magic-pdf/AnnotatedImageSlider.js.map +1 -1
- package/lib/features/magic-pdf/ExtractedContentView.js +4 -4
- package/lib/features/magic-pdf/ExtractedContentView.js.map +1 -1
- package/lib/features/magic-pdf/MagicPdfView.js +1 -1
- package/lib/features/magic-pdf/MagicPdfView.js.map +1 -1
- package/lib/features/pdf-viewer/PdfPageRenderer.js +2 -2
- package/lib/features/pdf-viewer/PdfPageRenderer.js.map +1 -1
- package/lib/features/pdf-viewer/PdfPageSlider.js +3 -3
- package/lib/features/pdf-viewer/PdfPageSlider.js.map +1 -1
- package/lib/features/pdf-viewer/SimplePdfViewer.js +1 -1
- package/lib/features/pdf-viewer/SimplePdfViewer.js.map +1 -1
- package/lib/features/permissions/UserPermissionsProvider.d.ts +2 -1
- package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
- package/lib/features/permissions/UserPermissionsProvider.js +35 -22
- package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
- package/lib/features/permissions/useRoleMappings.d.ts +19 -0
- package/lib/features/permissions/useRoleMappings.d.ts.map +1 -0
- package/lib/features/permissions/useRoleMappings.js +87 -0
- package/lib/features/permissions/useRoleMappings.js.map +1 -0
- package/lib/features/store/collections/SelectCollection.js +1 -1
- package/lib/features/store/collections/SelectCollection.js.map +1 -1
- package/lib/features/store/objects/DocumentPreviewPanel.d.ts.map +1 -1
- package/lib/features/store/objects/DocumentPreviewPanel.js +9 -9
- package/lib/features/store/objects/DocumentPreviewPanel.js.map +1 -1
- package/lib/features/store/objects/DocumentTable.js +1 -1
- package/lib/features/store/objects/DocumentTable.js.map +1 -1
- package/lib/features/store/objects/components/DocumentIcon.js +2 -2
- package/lib/features/store/objects/components/DocumentIcon.js.map +1 -1
- package/lib/features/store/objects/components/DocumentInput.js +1 -1
- package/lib/features/store/objects/components/DocumentInput.js.map +1 -1
- package/lib/features/store/objects/components/PropertiesEditorModal.js +1 -1
- package/lib/features/store/objects/components/PropertiesEditorModal.js.map +1 -1
- package/lib/features/store/objects/components/SaveVersionConfirmModal.js +1 -1
- package/lib/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
- package/lib/features/store/objects/layout/documentLayout.d.ts.map +1 -1
- package/lib/features/store/objects/layout/documentLayout.js +2 -2
- package/lib/features/store/objects/layout/documentLayout.js.map +1 -1
- package/lib/features/store/objects/selection/SelectionActions.js +1 -1
- package/lib/features/store/objects/selection/SelectionActions.js.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts +10 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.js +29 -19
- package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.d.ts +1 -1
- package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.js +5 -3
- package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.js +1 -1
- package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
- package/lib/features/user/UserAvatar.js +2 -2
- package/lib/features/user/UserAvatar.js.map +1 -1
- package/lib/features/user/UserInfo.d.ts.map +1 -1
- package/lib/features/user/UserInfo.js +7 -7
- package/lib/features/user/UserInfo.js.map +1 -1
- package/lib/features/utils/index.d.ts +1 -0
- package/lib/features/utils/index.d.ts.map +1 -1
- package/lib/features/utils/index.js +1 -0
- package/lib/features/utils/index.js.map +1 -1
- package/lib/features/utils/interaction.d.ts +55 -0
- package/lib/features/utils/interaction.d.ts.map +1 -0
- package/lib/features/utils/interaction.js +77 -0
- package/lib/features/utils/interaction.js.map +1 -0
- package/lib/features/views/ViewResults.js +2 -2
- package/lib/features/views/ViewResults.js.map +1 -1
- package/lib/i18n/locales/ar.json +7 -1
- package/lib/i18n/locales/de.json +7 -1
- package/lib/i18n/locales/en.json +7 -1
- package/lib/i18n/locales/es.json +7 -1
- package/lib/i18n/locales/fr.json +7 -1
- package/lib/i18n/locales/it.json +7 -1
- package/lib/i18n/locales/ja.json +7 -1
- package/lib/i18n/locales/ko.json +7 -1
- package/lib/i18n/locales/pt.json +7 -1
- package/lib/i18n/locales/ru.json +7 -1
- package/lib/i18n/locales/tr.json +7 -1
- package/lib/i18n/locales/zh-TW.json +7 -1
- package/lib/i18n/locales/zh.json +7 -1
- package/lib/layout/FullHeightLayout.js +2 -2
- package/lib/layout/FullHeightLayout.js.map +1 -1
- package/lib/layout/Navbar.js +4 -4
- package/lib/layout/Navbar.js.map +1 -1
- package/lib/layout/Sidebar.js +1 -1
- package/lib/layout/Sidebar.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +2 -13
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/authState.d.ts +13 -0
- package/lib/session/auth/authState.d.ts.map +1 -0
- package/lib/session/auth/authState.js +37 -0
- package/lib/session/auth/authState.js.map +1 -0
- package/lib/session/auth/domainRouting.d.ts +39 -0
- package/lib/session/auth/domainRouting.d.ts.map +1 -1
- package/lib/session/auth/domainRouting.js +85 -0
- package/lib/session/auth/domainRouting.js.map +1 -1
- package/lib/session/auth/useAuthState.d.ts +4 -7
- package/lib/session/auth/useAuthState.d.ts.map +1 -1
- package/lib/session/auth/useAuthState.js +5 -41
- package/lib/session/auth/useAuthState.js.map +1 -1
- package/lib/session/index.d.ts +1 -0
- package/lib/session/index.d.ts.map +1 -1
- package/lib/session/index.js +2 -0
- package/lib/session/index.js.map +1 -1
- package/lib/shell/SplashScreen.d.ts +1 -1
- package/lib/shell/SplashScreen.d.ts.map +1 -1
- package/lib/shell/SplashScreen.js +6 -2
- package/lib/shell/SplashScreen.js.map +1 -1
- package/lib/shell/VertesiaShell.js +1 -1
- package/lib/shell/VertesiaShell.js.map +1 -1
- package/lib/shell/apps/AppProjectSelector.js +1 -1
- package/lib/shell/apps/AppProjectSelector.js.map +1 -1
- package/lib/shell/apps/StandaloneApp.js +2 -2
- package/lib/shell/apps/StandaloneApp.js.map +1 -1
- package/lib/shell/login/SignInPrimitives.js +2 -2
- package/lib/shell/login/SignInPrimitives.js.map +1 -1
- package/lib/shell/login/SigninScreen.js +1 -1
- package/lib/shell/login/SigninScreen.js.map +1 -1
- package/lib/shell/login/SignupForm.js +1 -1
- package/lib/shell/login/SignupForm.js.map +1 -1
- package/lib/shell/login/TerminalLogin.js +2 -2
- package/lib/shell/login/TerminalLogin.js.map +1 -1
- package/lib/shell/login/UserInfo.d.ts.map +1 -1
- package/lib/shell/login/UserInfo.js +1 -1
- package/lib/shell/login/UserInfo.js.map +1 -1
- package/lib/shell/login/UserSessionMenu.js +1 -1
- package/lib/shell/login/UserSessionMenu.js.map +1 -1
- package/lib/vertesia-ui-core.js +7 -7
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +179 -182
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.BfN7iOHb.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BfN7iOHb.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BjH2zEZw.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BjH2zEZw.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BjSwAZXl.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BjSwAZXl.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.C7PUm5Au.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.C7PUm5Au.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.CF_1mUS5.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.CF_1mUS5.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.ChfUl3_-.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.ChfUl3_-.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.D-Sk-5d1.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.D-Sk-5d1.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.D4rnu1_S.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.D4rnu1_S.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DDf0-laK.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DDf0-laK.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DN79y06J.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DN79y06J.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DWLIciYQ.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DWLIciYQ.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DvF_YaAJ.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DvF_YaAJ.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.js +2 -2
- package/lib/vertesia-ui-layout.js +1 -1
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +24 -24
- package/lib/vertesia-ui-rich-text.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 +3 -3
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +54 -54
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/Progress.js +1 -1
- package/lib/widgets/Progress.js.map +1 -1
- package/lib/widgets/form/Form.js +2 -2
- package/lib/widgets/form/Form.js.map +1 -1
- package/lib/widgets/form/fields.js +2 -2
- package/lib/widgets/form/fields.js.map +1 -1
- package/lib/widgets/json-view/JSONView.js +1 -1
- package/lib/widgets/json-view/JSONView.js.map +1 -1
- package/lib/widgets/markdown/MermaidDiagram.js +1 -1
- package/lib/widgets/markdown/MermaidDiagram.js.map +1 -1
- package/lib/widgets/markdown/remarkDirectiveHandler.d.ts +7 -2
- package/lib/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -1
- package/lib/widgets/markdown/remarkDirectiveHandler.js +19 -4
- package/lib/widgets/markdown/remarkDirectiveHandler.js.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.js +4 -2
- package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/lib/widgets/monacoEditor/index.d.ts +1 -0
- package/lib/widgets/monacoEditor/index.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/index.js +1 -0
- package/lib/widgets/monacoEditor/index.js.map +1 -1
- package/lib/widgets/monacoEditor/loadMonaco.d.ts +45 -0
- package/lib/widgets/monacoEditor/loadMonaco.d.ts.map +1 -0
- package/lib/widgets/monacoEditor/loadMonaco.js +62 -0
- package/lib/widgets/monacoEditor/loadMonaco.js.map +1 -0
- package/lib/widgets/properties/PropertiesView.js +1 -1
- package/lib/widgets/properties/PropertiesView.js.map +1 -1
- package/lib/widgets/schema-editor/editor/Editable.js +2 -2
- package/lib/widgets/schema-editor/editor/Editable.js.map +1 -1
- package/lib/widgets/schema-editor/editor/PropertyEditor.js +1 -1
- package/lib/widgets/schema-editor/editor/PropertyEditor.js.map +1 -1
- package/lib/widgets/schema-editor/editor/SchemaEditor.js +2 -2
- package/lib/widgets/schema-editor/editor/SchemaEditor.js.map +1 -1
- package/lib/widgets/upload/DropZone.js +1 -1
- package/lib/widgets/upload/DropZone.js.map +1 -1
- package/lib/widgets/upload/UploadResultCategory.d.ts +1 -1
- package/lib/widgets/upload/UploadResultCategory.d.ts.map +1 -1
- package/lib/widgets/upload/UploadResultCategory.js +3 -3
- package/lib/widgets/upload/UploadResultCategory.js.map +1 -1
- package/lib/widgets/upload/UploadSummary.js +1 -1
- package/lib/widgets/upload/UploadSummary.js.map +1 -1
- package/lib/widgets/xml-viewer/components/XMLViewer.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/components/XMLViewer.js +7 -3
- package/lib/widgets/xml-viewer/components/XMLViewer.js.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +11 -13
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +41 -14
- package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/contrast.test.ts +1 -0
- package/src/core/components/Avatar.tsx +3 -3
- package/src/core/components/ComboBox.tsx +1 -1
- package/src/core/components/FileUpload.tsx +4 -4
- package/src/core/components/Link.tsx +1 -1
- package/src/core/components/SelectList.tsx +1 -1
- package/src/core/components/SidePanel.tsx +1 -1
- package/src/core/components/Spinner.tsx +1 -1
- package/src/core/components/TagsInput.tsx +8 -8
- package/src/core/components/shadcn/MessageBox.tsx +1 -1
- package/src/core/components/shadcn/button.tsx +1 -1
- package/src/core/components/shadcn/card.tsx +1 -3
- package/src/core/components/shadcn/command.tsx +5 -5
- package/src/core/components/shadcn/filters/DynamicLabel.tsx +1 -1
- package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +3 -3
- package/src/core/components/shadcn/input.tsx +3 -3
- package/src/core/components/shadcn/modal/ConfirmModal.tsx +3 -3
- package/src/core/components/shadcn/modal/dialog.tsx +2 -4
- package/src/core/components/shadcn/overflowTabs.tsx +2 -2
- package/src/core/components/shadcn/popover.tsx +1 -1
- package/src/core/components/shadcn/radioGroup.tsx +5 -7
- package/src/core/components/shadcn/selectBox.tsx +1 -1
- package/src/core/components/shadcn/tabs.tsx +4 -2
- package/src/core/components/styles.ts +1 -1
- package/src/core/components/table/index.tsx +1 -1
- package/src/core/hooks/useFetch.test.ts +20 -0
- package/src/core/hooks/useFetch.ts +2 -0
- package/src/css/base.css +1 -1
- package/src/css/color.css +4 -0
- package/src/css/theme.css +1 -0
- package/src/css/typography.css +2 -2
- package/src/features/activity-doc/ActivityDoc.tsx +11 -11
- package/src/features/agent/chat/AgentChart.tsx +1 -1
- package/src/features/agent/chat/AskUserWidget.tsx +19 -23
- package/src/features/agent/chat/JumpingDots.tsx +3 -3
- package/src/features/agent/chat/ModernAgentConversation.tsx +3 -3
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +60 -1
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +44 -24
- package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +12 -12
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.tsx +4 -4
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +2 -2
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +7 -12
- package/src/features/agent/chat/ModernAgentOutput/MessagesContainer.tsx +1 -1
- package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +16 -22
- package/src/features/agent/chat/ModernAgentOutput/SlideInPanel.tsx +4 -4
- package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +2 -4
- package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +21 -21
- package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +4 -4
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +16 -1
- package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +19 -40
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +41 -0
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +19 -0
- package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +93 -0
- package/src/features/agent/chat/SlidingThinkingIndicator.tsx +5 -2
- package/src/features/agent/chat/VegaLiteChart.tsx +6 -2
- package/src/features/errors/RowErrorBoundary.tsx +1 -1
- package/src/features/facets/AgentRunnerFacetsNav.tsx +1 -1
- package/src/features/facets/utils/VInteractionFacet.tsx +22 -34
- package/src/features/facets/utils/VUserFacet.tsx +1 -1
- package/src/features/layout/GenericPageNavHeader.tsx +9 -1
- package/src/features/layout/NotFoundView.tsx +1 -1
- package/src/features/magic-pdf/AnnotatedImageSlider.tsx +8 -16
- package/src/features/magic-pdf/ExtractedContentView.tsx +4 -4
- package/src/features/magic-pdf/MagicPdfView.tsx +1 -1
- package/src/features/pdf-viewer/PdfPageRenderer.tsx +2 -2
- package/src/features/pdf-viewer/PdfPageSlider.tsx +4 -4
- package/src/features/pdf-viewer/SimplePdfViewer.tsx +1 -1
- package/src/features/permissions/UserPermissionsProvider.test.tsx +172 -0
- package/src/features/permissions/UserPermissionsProvider.tsx +68 -21
- package/src/features/permissions/useRoleMappings.ts +105 -0
- package/src/features/store/collections/SelectCollection.tsx +1 -1
- package/src/features/store/objects/DocumentPreviewPanel.tsx +43 -53
- package/src/features/store/objects/DocumentTable.tsx +2 -2
- package/src/features/store/objects/components/DocumentIcon.tsx +4 -4
- package/src/features/store/objects/components/DocumentInput.tsx +3 -3
- package/src/features/store/objects/components/PropertiesEditorModal.tsx +2 -2
- package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +2 -2
- package/src/features/store/objects/layout/documentLayout.tsx +2 -4
- package/src/features/store/objects/selection/SelectionActions.tsx +1 -1
- package/src/features/store/types/IntakePolicyEditor.tsx +70 -36
- package/src/features/store/types/IntakePolicyForm.tsx +11 -3
- package/src/features/store/types/SelectContentTypeModal.tsx +1 -1
- package/src/features/user/UserAvatar.tsx +3 -3
- package/src/features/user/UserInfo.tsx +11 -16
- package/src/features/utils/index.ts +1 -0
- package/src/features/utils/interaction.test.tsx +93 -0
- package/src/features/utils/interaction.tsx +125 -0
- package/src/features/views/ViewResults.tsx +3 -3
- package/src/i18n/locales/ar.json +7 -1
- package/src/i18n/locales/de.json +7 -1
- package/src/i18n/locales/en.json +7 -1
- package/src/i18n/locales/es.json +7 -1
- package/src/i18n/locales/fr.json +7 -1
- package/src/i18n/locales/it.json +7 -1
- package/src/i18n/locales/ja.json +7 -1
- package/src/i18n/locales/ko.json +7 -1
- package/src/i18n/locales/pt.json +7 -1
- package/src/i18n/locales/ru.json +7 -1
- package/src/i18n/locales/tr.json +7 -1
- package/src/i18n/locales/zh-TW.json +7 -1
- package/src/i18n/locales/zh.json +7 -1
- package/src/layout/FullHeightLayout.tsx +2 -2
- package/src/layout/Navbar.tsx +5 -5
- package/src/layout/Sidebar.tsx +1 -1
- package/src/session/UserSessionProvider.tsx +2 -15
- package/src/session/auth/authState.test.ts +35 -0
- package/src/session/auth/authState.ts +42 -0
- package/src/session/auth/domainRouting.test.ts +169 -1
- package/src/session/auth/domainRouting.ts +89 -0
- package/src/session/auth/useAuthState.ts +5 -49
- package/src/session/index.ts +6 -0
- package/src/shell/SplashScreen.test.tsx +22 -0
- package/src/shell/SplashScreen.tsx +6 -2
- package/src/shell/VertesiaShell.tsx +1 -1
- package/src/shell/apps/AppProjectSelector.tsx +1 -1
- package/src/shell/apps/StandaloneApp.tsx +9 -9
- package/src/shell/login/SignInPrimitives.tsx +2 -2
- package/src/shell/login/SigninScreen.tsx +1 -1
- package/src/shell/login/SignupForm.tsx +2 -2
- package/src/shell/login/TerminalLogin.tsx +5 -5
- package/src/shell/login/UserInfo.tsx +2 -5
- package/src/shell/login/UserSessionMenu.tsx +2 -2
- package/src/widgets/Progress.tsx +2 -2
- package/src/widgets/form/Form.tsx +4 -4
- package/src/widgets/form/fields.tsx +2 -2
- package/src/widgets/json-view/JSONView.tsx +1 -6
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +33 -29
- package/src/widgets/markdown/MarkdownRenderer.test.tsx +52 -0
- package/src/widgets/markdown/MermaidDiagram.tsx +2 -2
- package/src/widgets/markdown/remarkDirectiveHandler.ts +21 -5
- package/src/widgets/monacoEditor/MonacoEditor.tsx +4 -2
- package/src/widgets/monacoEditor/index.ts +1 -0
- package/src/widgets/monacoEditor/loadMonaco.test.ts +63 -0
- package/src/widgets/monacoEditor/loadMonaco.ts +70 -0
- package/src/widgets/properties/PropertiesView.tsx +1 -1
- package/src/widgets/schema-editor/editor/Editable.tsx +2 -2
- package/src/widgets/schema-editor/editor/PropertyEditor.tsx +1 -1
- package/src/widgets/schema-editor/editor/SchemaEditor.tsx +2 -2
- package/src/widgets/upload/DropZone.tsx +1 -1
- package/src/widgets/upload/UploadResultCategory.tsx +7 -7
- package/src/widgets/upload/UploadSummary.tsx +4 -4
- package/src/widgets/xml-viewer/components/XMLViewer.tsx +7 -3
- package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +60 -7
- package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +70 -16
- package/lib/vertesia-ui-i18n.3yHWompP.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.3yHWompP.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.4XKCcnL0.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.4XKCcnL0.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.78KG4J25.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.78KG4J25.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BN06mpp1.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BN06mpp1.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.CSzKLlHJ.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.CSzKLlHJ.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.Ccus7aRh.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.Ccus7aRh.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.D9j3c6gI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.D9j3c6gI.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.DAUg4rrI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.DAUg4rrI.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.DSxVZKXy.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.DSxVZKXy.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.aahVhHvR.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.aahVhHvR.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.nZ3xJ26v.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.nZ3xJ26v.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.xPYbuFzT.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.xPYbuFzT.chunk.js.map +0 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FacetBucket } from '@vertesia/common';
|
|
2
2
|
import { Badge, type FilterGroup } from '@vertesia/ui/core';
|
|
3
|
+
import {
|
|
4
|
+
type InteractionDisplayRef,
|
|
5
|
+
InteractionStatusBadge,
|
|
6
|
+
resolveInteractionName,
|
|
7
|
+
splitInteractionType,
|
|
8
|
+
} from '../../utils/interaction.js';
|
|
3
9
|
|
|
4
|
-
export interface EnrichedFacetBucket extends FacetBucket {
|
|
5
|
-
name?: string;
|
|
6
|
-
status?: string;
|
|
7
|
-
version?: number;
|
|
8
|
-
}
|
|
10
|
+
export interface EnrichedFacetBucket extends FacetBucket, InteractionDisplayRef {}
|
|
9
11
|
|
|
10
12
|
interface InteractionFacetProps {
|
|
11
13
|
buckets: EnrichedFacetBucket[];
|
|
@@ -13,6 +15,11 @@ interface InteractionFacetProps {
|
|
|
13
15
|
placeholder?: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
/** The name this facet displays for a bucket — the same one the runs table shows for the run. */
|
|
19
|
+
function bucketName(bucket: EnrichedFacetBucket | undefined, interactionId: string): string {
|
|
20
|
+
return resolveInteractionName(bucket, interactionId) ?? interactionId;
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
export function VInteractionFacet({ buckets, name, placeholder }: InteractionFacetProps): FilterGroup {
|
|
17
24
|
const options = buckets.map((bucket) => ({
|
|
18
25
|
label: `(${bucket.count})`,
|
|
@@ -26,38 +33,20 @@ export function VInteractionFacet({ buckets, name, placeholder }: InteractionFac
|
|
|
26
33
|
type: 'select',
|
|
27
34
|
labelRenderer: (interactionId: string) => {
|
|
28
35
|
const bucket = buckets.find((b) => b._id === interactionId);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
let badgeVariant: 'success' | 'info' | 'destructive' | 'default' = 'success';
|
|
33
|
-
if (bucket?.status) {
|
|
34
|
-
switch (bucket.status) {
|
|
35
|
-
case InteractionStatus.published:
|
|
36
|
-
badgeVariant = 'success';
|
|
37
|
-
break;
|
|
38
|
-
case InteractionStatus.archived:
|
|
39
|
-
badgeVariant = 'destructive';
|
|
40
|
-
break;
|
|
41
|
-
case InteractionStatus.code:
|
|
42
|
-
badgeVariant = 'info';
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const badgeText =
|
|
48
|
-
bucket?.version && bucket?.status
|
|
49
|
-
? `v${bucket.version} ${bucket.status !== InteractionStatus.unknown ? bucket.status : ''}`
|
|
50
|
-
: bucket?.status || (bucket?.version ? `v${bucket.version}` : '');
|
|
36
|
+
// Same split as the runs table: the `sys`/`app`/`tmp` namespace becomes its own badge
|
|
37
|
+
// instead of staying glued to the name.
|
|
38
|
+
const { type, label } = splitInteractionType(bucketName(bucket, interactionId));
|
|
51
39
|
|
|
52
40
|
return (
|
|
53
41
|
<div className="w-full flex items-center justify-between">
|
|
54
42
|
<div className="flex flex-row flex-wrap items-center gap-2 min-w-0 flex-1">
|
|
55
|
-
<span className="text-sm truncate">{
|
|
56
|
-
{
|
|
57
|
-
<Badge variant=
|
|
58
|
-
{
|
|
43
|
+
<span className="text-sm truncate">{label}</span>
|
|
44
|
+
{type && (
|
|
45
|
+
<Badge variant="secondary" className="text-xs w-fit">
|
|
46
|
+
{type}
|
|
59
47
|
</Badge>
|
|
60
48
|
)}
|
|
49
|
+
{bucket && <InteractionStatusBadge interaction={bucket} className="text-xs w-fit" />}
|
|
61
50
|
</div>
|
|
62
51
|
{(bucket?.count ?? 0) > 0 && <span className="ms-2 text-xs shrink-0">({bucket?.count})</span>}
|
|
63
52
|
</div>
|
|
@@ -65,8 +54,7 @@ export function VInteractionFacet({ buckets, name, placeholder }: InteractionFac
|
|
|
65
54
|
},
|
|
66
55
|
filterBy: (optionValue: string, searchText: string) => {
|
|
67
56
|
const bucket = buckets.find((b) => b._id === optionValue);
|
|
68
|
-
|
|
69
|
-
return searchName.toLowerCase().includes(searchText.toLowerCase());
|
|
57
|
+
return bucketName(bucket, optionValue).toLowerCase().includes(searchText.toLowerCase());
|
|
70
58
|
},
|
|
71
59
|
};
|
|
72
60
|
|
|
@@ -36,7 +36,7 @@ export function createUserFilterGroup({ buckets, name, placeholder }: UserFacetP
|
|
|
36
36
|
<div className="flex-1 min-w-0 flex items-center truncate">
|
|
37
37
|
<UserInfo userRef={userRef} showTitle={true} size="sm" />
|
|
38
38
|
</div>
|
|
39
|
-
<span className="text-muted
|
|
39
|
+
<span className="text-muted flex-shrink-0">({bucket?.count || 0})</span>
|
|
40
40
|
</div>
|
|
41
41
|
);
|
|
42
42
|
},
|
|
@@ -148,6 +148,9 @@ export function GenericPageNavHeader({
|
|
|
148
148
|
};
|
|
149
149
|
|
|
150
150
|
const breadcrumbItems = buildBreadcrumbItems();
|
|
151
|
+
// The description tooltip trails the last element of the header: the breadcrumbs when there
|
|
152
|
+
// are any, otherwise the title.
|
|
153
|
+
const showDescriptionWithTitle = !!title && breadcrumbItems.length === 0;
|
|
151
154
|
|
|
152
155
|
return (
|
|
153
156
|
<div className={clsx('pb-0 ps-4 pe-2 py-2 flex flex-col', className)}>
|
|
@@ -161,7 +164,7 @@ export function GenericPageNavHeader({
|
|
|
161
164
|
maxItems={4}
|
|
162
165
|
/>
|
|
163
166
|
)}
|
|
164
|
-
{description && (
|
|
167
|
+
{description && !showDescriptionWithTitle && (
|
|
165
168
|
<VTooltip description={description}>
|
|
166
169
|
<Info className="size-4 text-muted ms-4" />
|
|
167
170
|
</VTooltip>
|
|
@@ -170,6 +173,11 @@ export function GenericPageNavHeader({
|
|
|
170
173
|
{title && (
|
|
171
174
|
<div className="flex gap-2 items-center">
|
|
172
175
|
<h1 className="text-xl font-semibold break-all">{title}</h1>
|
|
176
|
+
{description && showDescriptionWithTitle && (
|
|
177
|
+
<VTooltip description={description}>
|
|
178
|
+
<Info className="size-4 text-muted" />
|
|
179
|
+
</VTooltip>
|
|
180
|
+
)}
|
|
173
181
|
</div>
|
|
174
182
|
)}
|
|
175
183
|
</div>
|
|
@@ -4,7 +4,7 @@ export function NotFoundView() {
|
|
|
4
4
|
const { t } = useUITranslation();
|
|
5
5
|
return (
|
|
6
6
|
<div className="text-center pt-32">
|
|
7
|
-
<h1 className="text-3xl font-bold text-
|
|
7
|
+
<h1 className="text-3xl font-bold text-destructive">404</h1>
|
|
8
8
|
<p className="text-2xl">{t('layout.pageNotFound')}</p>
|
|
9
9
|
</div>
|
|
10
10
|
);
|
|
@@ -326,9 +326,7 @@ function ImageTypeButton({ type, currentType, onClick, icon, tooltip }: ImageTyp
|
|
|
326
326
|
aria-pressed={isSelected}
|
|
327
327
|
className={clsx(
|
|
328
328
|
'p-1 rounded cursor-pointer transition-colors',
|
|
329
|
-
isSelected
|
|
330
|
-
? 'text-primary bg-primary/10'
|
|
331
|
-
: 'text-muted-foreground hover:text-foreground hover:bg-muted',
|
|
329
|
+
isSelected ? 'text-primary bg-primary/10' : 'text-muted hover:text-foreground hover:bg-muted',
|
|
332
330
|
)}
|
|
333
331
|
onClick={onClick}
|
|
334
332
|
>
|
|
@@ -355,25 +353,21 @@ function ZoomControls({ zoom, onZoomIn, onZoomOut, onFitToView, canZoomIn, canZo
|
|
|
355
353
|
variant="unstyled"
|
|
356
354
|
className={clsx(
|
|
357
355
|
'p-1 rounded cursor-pointer transition-colors',
|
|
358
|
-
canZoomOut
|
|
359
|
-
? 'text-muted-foreground hover:text-foreground hover:bg-muted'
|
|
360
|
-
: 'text-muted-foreground/40 cursor-not-allowed',
|
|
356
|
+
canZoomOut ? 'text-muted hover:text-foreground hover:bg-muted' : 'text-muted/40 cursor-not-allowed',
|
|
361
357
|
)}
|
|
362
358
|
onClick={onZoomOut}
|
|
363
359
|
disabled={!canZoomOut}
|
|
364
360
|
>
|
|
365
361
|
<Minus className="size-4" />
|
|
366
362
|
</Button>
|
|
367
|
-
<span className="text-xs text-muted
|
|
363
|
+
<span className="text-xs text-muted min-w-[32px] text-center">{zoom}%</span>
|
|
368
364
|
<Button
|
|
369
365
|
title={t('pdf.zoomIn')}
|
|
370
366
|
tooltipPlacement="bottom"
|
|
371
367
|
variant="unstyled"
|
|
372
368
|
className={clsx(
|
|
373
369
|
'p-1 rounded cursor-pointer transition-colors',
|
|
374
|
-
canZoomIn
|
|
375
|
-
? 'text-muted-foreground hover:text-foreground hover:bg-muted'
|
|
376
|
-
: 'text-muted-foreground/40 cursor-not-allowed',
|
|
370
|
+
canZoomIn ? 'text-muted hover:text-foreground hover:bg-muted' : 'text-muted/40 cursor-not-allowed',
|
|
377
371
|
)}
|
|
378
372
|
onClick={onZoomIn}
|
|
379
373
|
disabled={!canZoomIn}
|
|
@@ -386,9 +380,7 @@ function ZoomControls({ zoom, onZoomIn, onZoomOut, onFitToView, canZoomIn, canZo
|
|
|
386
380
|
variant="unstyled"
|
|
387
381
|
className={clsx(
|
|
388
382
|
'p-1 rounded cursor-pointer transition-colors',
|
|
389
|
-
zoom !== DEFAULT_ZOOM
|
|
390
|
-
? 'text-muted-foreground hover:text-foreground hover:bg-muted'
|
|
391
|
-
: 'text-muted-foreground/40',
|
|
383
|
+
zoom !== DEFAULT_ZOOM ? 'text-muted hover:text-foreground hover:bg-muted' : 'text-muted/40',
|
|
392
384
|
)}
|
|
393
385
|
onClick={onFitToView}
|
|
394
386
|
>
|
|
@@ -431,10 +423,10 @@ function PageThumbnail({ pageNumber, currentPage, aspectRatio, zoom, url, onSele
|
|
|
431
423
|
{url ? (
|
|
432
424
|
<img src={url} alt={`Page ${pageNumber}`} className="w-full" />
|
|
433
425
|
) : (
|
|
434
|
-
<Loader2 className="w-6 h-6 animate-spin text-muted
|
|
426
|
+
<Loader2 className="w-6 h-6 animate-spin text-muted" />
|
|
435
427
|
)}
|
|
436
428
|
</Button>
|
|
437
|
-
<Center className="text-sm text-muted
|
|
429
|
+
<Center className="text-sm text-muted pt-1 font-semibold">{pageNumber}</Center>
|
|
438
430
|
</div>
|
|
439
431
|
);
|
|
440
432
|
}
|
|
@@ -479,7 +471,7 @@ function PageNavigator({ currentPage, totalPages, onChange }: PageNavigatorProps
|
|
|
479
471
|
};
|
|
480
472
|
|
|
481
473
|
return (
|
|
482
|
-
<div className="flex items-center gap-1 text-xs text-muted
|
|
474
|
+
<div className="flex items-center gap-1 text-xs text-muted">
|
|
483
475
|
<span>{t('pdf.page')}</span>
|
|
484
476
|
<input
|
|
485
477
|
ref={inputRef}
|
|
@@ -7,7 +7,7 @@ import type { ViewType } from './types';
|
|
|
7
7
|
function LoadingSpinner({ className }: { className?: string }) {
|
|
8
8
|
return (
|
|
9
9
|
<div className={`flex items-center justify-center ${className || ''}`}>
|
|
10
|
-
<Loader2 className="w-6 h-6 animate-spin text-
|
|
10
|
+
<Loader2 className="w-6 h-6 animate-spin text-muted" />
|
|
11
11
|
</div>
|
|
12
12
|
);
|
|
13
13
|
}
|
|
@@ -61,7 +61,7 @@ function JsonPageLayoutView({ pageNumber }: JsonPageLayoutViewProps) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
if (error) {
|
|
64
|
-
return <div className="px-4 py-2 text-
|
|
64
|
+
return <div className="px-4 py-2 text-destructive text-sm">{error}</div>;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
return content ? <JSONCode className="w-full" data={content} /> : null;
|
|
@@ -96,13 +96,13 @@ function MarkdownPageView({ pageNumber }: MarkdownPageViewProps) {
|
|
|
96
96
|
return (
|
|
97
97
|
<div className="h-full flex flex-col items-center justify-center gap-2">
|
|
98
98
|
<LoadingSpinner />
|
|
99
|
-
<span className="text-sm text-muted
|
|
99
|
+
<span className="text-sm text-muted">Loading...</span>
|
|
100
100
|
</div>
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
if (error) {
|
|
105
|
-
return <div className="px-4 py-2 text-
|
|
105
|
+
return <div className="px-4 py-2 text-destructive text-sm">{error}</div>;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
return (
|
|
@@ -144,7 +144,7 @@ function MagicPdfViewImpl({ object, onClose }: _MagicPdfViewProps) {
|
|
|
144
144
|
<div className="flex items-center gap-x-2">
|
|
145
145
|
<DownloadPopover object={object} />
|
|
146
146
|
</div>
|
|
147
|
-
<span className="text-xs text-muted
|
|
147
|
+
<span className="text-xs text-muted">{t('pdf.pageOf', { pageNumber, totalPages })}</span>
|
|
148
148
|
<div className="flex items-center gap-x-2">
|
|
149
149
|
{!!onClose && (
|
|
150
150
|
<Button variant="ghost" size="xs" onClick={onClose} title={t('pdf.close')}>
|
|
@@ -11,7 +11,7 @@ function LoadingSpinner({ className, size = 'md' }: { className?: string; size?:
|
|
|
11
11
|
};
|
|
12
12
|
return (
|
|
13
13
|
<div className={`flex items-center justify-center ${className || ''}`}>
|
|
14
|
-
<Loader2 className={`${sizeClasses[size]} animate-spin text-muted
|
|
14
|
+
<Loader2 className={`${sizeClasses[size]} animate-spin text-muted`} />
|
|
15
15
|
</div>
|
|
16
16
|
);
|
|
17
17
|
}
|
|
@@ -327,7 +327,7 @@ function VirtualizedThumbnail({
|
|
|
327
327
|
className="flex items-center justify-center bg-muted"
|
|
328
328
|
style={{ height: placeholderHeight, width: width || '100%' }}
|
|
329
329
|
>
|
|
330
|
-
<span className="text-muted
|
|
330
|
+
<span className="text-muted text-xs">{pageNumber}</span>
|
|
331
331
|
</div>
|
|
332
332
|
);
|
|
333
333
|
|
|
@@ -367,7 +367,7 @@ export function PdfPageSlider({
|
|
|
367
367
|
</Button>
|
|
368
368
|
<Center
|
|
369
369
|
className={clsx(
|
|
370
|
-
'text-muted
|
|
370
|
+
'text-muted font-semibold',
|
|
371
371
|
compact ? 'text-xs pt-0.5' : 'text-sm pt-1',
|
|
372
372
|
)}
|
|
373
373
|
>
|
|
@@ -426,7 +426,7 @@ function PageNavigator({ currentPage, totalPages, onChange }: PageNavigatorProps
|
|
|
426
426
|
};
|
|
427
427
|
|
|
428
428
|
return (
|
|
429
|
-
<div className="flex items-center gap-1 text-xs text-muted
|
|
429
|
+
<div className="flex items-center gap-1 text-xs text-muted">
|
|
430
430
|
<span>{t('pdf.page')}</span>
|
|
431
431
|
<input
|
|
432
432
|
ref={inputRef}
|
|
@@ -457,7 +457,7 @@ function ZoomControls({ zoom, onZoomIn, onZoomOut, onFitToView, canZoomIn, canZo
|
|
|
457
457
|
<Button variant="ghost" size="xs" onClick={onZoomOut} isDisabled={!canZoomOut} title={t('pdf.zoomOut')}>
|
|
458
458
|
<Minus />
|
|
459
459
|
</Button>
|
|
460
|
-
<span className="text-xs text-muted
|
|
460
|
+
<span className="text-xs text-muted min-w-[32px] text-center">{zoom}%</span>
|
|
461
461
|
<Button variant="ghost" size="xs" onClick={onZoomIn} isDisabled={!canZoomIn} title={t('pdf.zoomIn')}>
|
|
462
462
|
<Plus />
|
|
463
463
|
</Button>
|
|
@@ -466,7 +466,7 @@ function ZoomControls({ zoom, onZoomIn, onZoomOut, onFitToView, canZoomIn, canZo
|
|
|
466
466
|
size="xs"
|
|
467
467
|
onClick={onFitToView}
|
|
468
468
|
title={t('pdf.fitToWidth')}
|
|
469
|
-
className={zoom === DEFAULT_ZOOM ? 'text-muted
|
|
469
|
+
className={zoom === DEFAULT_ZOOM ? 'text-muted/40' : undefined}
|
|
470
470
|
>
|
|
471
471
|
<Maximize />
|
|
472
472
|
</Button>
|
|
@@ -135,7 +135,7 @@ export function SimplePdfViewer({ object, url, source, className }: SimplePdfVie
|
|
|
135
135
|
title={t('pdf.fullscreen')}
|
|
136
136
|
tooltipPlacement="bottom"
|
|
137
137
|
variant="unstyled"
|
|
138
|
-
className="p-1 rounded cursor-pointer transition-colors text-muted
|
|
138
|
+
className="p-1 rounded cursor-pointer transition-colors text-muted hover:text-foreground hover:bg-muted"
|
|
139
139
|
onClick={() => setIsFullscreen(true)}
|
|
140
140
|
>
|
|
141
141
|
<Maximize2 className="size-4" />
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { act, fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { VertesiaClient } from '@vertesia/client';
|
|
3
|
+
import type { AuthTokenPayload, SystemRoleDefinition } from '@vertesia/common';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { UserPermissionProvider } from './UserPermissionsProvider';
|
|
6
|
+
|
|
7
|
+
const session = {
|
|
8
|
+
client: new VertesiaClient({ serverUrl: 'https://studio.example.test', storeUrl: 'https://store.example.test' }),
|
|
9
|
+
authToken: { sub: 'user-a', account_roles: [] } as unknown as AuthTokenPayload,
|
|
10
|
+
signOut: vi.fn(),
|
|
11
|
+
};
|
|
12
|
+
vi.mock('@vertesia/ui/session', () => ({ useUserSession: () => session }));
|
|
13
|
+
|
|
14
|
+
function renderProvider() {
|
|
15
|
+
return render(
|
|
16
|
+
<UserPermissionProvider>
|
|
17
|
+
<div>Protected workspace</div>
|
|
18
|
+
</UserPermissionProvider>,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function advance(ms: number) {
|
|
23
|
+
await act(async () => {
|
|
24
|
+
await vi.advanceTimersByTimeAsync(ms);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('role mapping recovery', () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
vi.useFakeTimers();
|
|
31
|
+
vi.spyOn(Math, 'random').mockReturnValue(1);
|
|
32
|
+
session.authToken = { sub: 'user-a', account_roles: [] } as unknown as AuthTokenPayload;
|
|
33
|
+
session.signOut.mockClear();
|
|
34
|
+
});
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
vi.useRealTimers();
|
|
37
|
+
vi.restoreAllMocks();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it.each([0, 502, 503, 504])(
|
|
41
|
+
'recovers automatically from status %s without rendering protected content early',
|
|
42
|
+
async (status) => {
|
|
43
|
+
const fetch = vi
|
|
44
|
+
.spyOn(session.client.iam.roles, 'listSystem')
|
|
45
|
+
.mockRejectedValueOnce(Object.assign(new Error('JWKSTimeout'), { status }))
|
|
46
|
+
.mockResolvedValue([]);
|
|
47
|
+
renderProvider();
|
|
48
|
+
expect(screen.queryByText('Protected workspace')).toBeNull();
|
|
49
|
+
await advance(0);
|
|
50
|
+
expect(screen.getByRole('status').textContent).toContain('automatically');
|
|
51
|
+
expect(screen.queryByText('JWKSTimeout')).toBeNull();
|
|
52
|
+
await advance(1_000);
|
|
53
|
+
expect(screen.getByText('Protected workspace')).toBeTruthy();
|
|
54
|
+
expect(fetch).toHaveBeenCalledTimes(2);
|
|
55
|
+
expect(screen.queryByRole('alert')).toBeNull();
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
it('stops after one minute and lets a manual retry recover without navigating', async () => {
|
|
60
|
+
const fetch = vi
|
|
61
|
+
.spyOn(session.client.iam.roles, 'listSystem')
|
|
62
|
+
.mockRejectedValue(Object.assign(new Error('JWKSTimeout'), { status: 503 }));
|
|
63
|
+
const location = window.location.href;
|
|
64
|
+
renderProvider();
|
|
65
|
+
await advance(60_000);
|
|
66
|
+
expect(screen.getByRole('alert').textContent).toContain('couldn’t connect');
|
|
67
|
+
const calls = fetch.mock.calls.length;
|
|
68
|
+
await advance(60_000);
|
|
69
|
+
expect(fetch).toHaveBeenCalledTimes(calls);
|
|
70
|
+
fetch.mockResolvedValue([]);
|
|
71
|
+
fireEvent.click(screen.getByRole('button', { name: 'Try again' }));
|
|
72
|
+
await advance(0);
|
|
73
|
+
expect(screen.getByText('Protected workspace')).toBeTruthy();
|
|
74
|
+
expect(window.location.href).toBe(location);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('does not restart recovery when authentication re-decodes the same JWT', async () => {
|
|
78
|
+
const fetch = vi.spyOn(session.client.iam.roles, 'listSystem').mockImplementation(async () => {
|
|
79
|
+
session.authToken = { ...session.authToken };
|
|
80
|
+
throw Object.assign(new Error('Unavailable'), { status: 503 });
|
|
81
|
+
});
|
|
82
|
+
renderProvider();
|
|
83
|
+
await advance(60_000);
|
|
84
|
+
expect(screen.getByRole('button', { name: 'Try again' })).toBeTruthy();
|
|
85
|
+
const calls = fetch.mock.calls.length;
|
|
86
|
+
await advance(10_000);
|
|
87
|
+
expect(fetch).toHaveBeenCalledTimes(calls);
|
|
88
|
+
fetch.mockImplementation(async () => {
|
|
89
|
+
session.authToken = { ...session.authToken };
|
|
90
|
+
return [];
|
|
91
|
+
});
|
|
92
|
+
fireEvent.click(screen.getByRole('button', { name: 'Try again' }));
|
|
93
|
+
await advance(0);
|
|
94
|
+
expect(screen.getByText('Protected workspace')).toBeTruthy();
|
|
95
|
+
expect(fetch).toHaveBeenCalledTimes(calls + 1);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('bounds a hung request and ignores its late success', async () => {
|
|
99
|
+
let resolve!: (roles: SystemRoleDefinition[]) => void;
|
|
100
|
+
const fetch = vi.spyOn(session.client.iam.roles, 'listSystem').mockImplementation(
|
|
101
|
+
() =>
|
|
102
|
+
new Promise((done) => {
|
|
103
|
+
resolve = done;
|
|
104
|
+
}),
|
|
105
|
+
);
|
|
106
|
+
renderProvider();
|
|
107
|
+
await advance(60_000);
|
|
108
|
+
expect(fetch.mock.calls[0][0]?.signal?.aborted).toBe(true);
|
|
109
|
+
await act(async () => resolve([]));
|
|
110
|
+
expect(screen.queryByText('Protected workspace')).toBeNull();
|
|
111
|
+
expect(screen.getByRole('button', { name: 'Try again' })).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it.each([401, 403, 400, 500])('does not automatically retry status %s', async (status) => {
|
|
115
|
+
const fetch = vi
|
|
116
|
+
.spyOn(session.client.iam.roles, 'listSystem')
|
|
117
|
+
.mockRejectedValue(Object.assign(new Error('Request failed'), { status }));
|
|
118
|
+
renderProvider();
|
|
119
|
+
await advance(60_000);
|
|
120
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
121
|
+
expect(screen.queryByText('Protected workspace')).toBeNull();
|
|
122
|
+
if (status === 401 || status === 403) {
|
|
123
|
+
fireEvent.click(screen.getByRole('button', { name: 'Use a different account' }));
|
|
124
|
+
expect(session.signOut).toHaveBeenCalledOnce();
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('cancels retries on unmount', async () => {
|
|
129
|
+
const fetch = vi
|
|
130
|
+
.spyOn(session.client.iam.roles, 'listSystem')
|
|
131
|
+
.mockRejectedValue(Object.assign(new Error('Unavailable'), { status: 503 }));
|
|
132
|
+
const view = renderProvider();
|
|
133
|
+
await advance(0);
|
|
134
|
+
view.unmount();
|
|
135
|
+
await advance(60_000);
|
|
136
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
137
|
+
expect(fetch.mock.calls[0][0]?.signal?.aborted).toBe(true);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('ignores the previous session’s pending response after a token change', async () => {
|
|
141
|
+
let resolveOld!: (roles: SystemRoleDefinition[]) => void;
|
|
142
|
+
const fetch = vi
|
|
143
|
+
.spyOn(session.client.iam.roles, 'listSystem')
|
|
144
|
+
.mockImplementationOnce(
|
|
145
|
+
() =>
|
|
146
|
+
new Promise((done) => {
|
|
147
|
+
resolveOld = done;
|
|
148
|
+
}),
|
|
149
|
+
)
|
|
150
|
+
.mockRejectedValue(Object.assign(new Error('Forbidden'), { status: 403 }));
|
|
151
|
+
const view = renderProvider();
|
|
152
|
+
session.authToken = { sub: 'user-b', account_roles: [] } as unknown as AuthTokenPayload;
|
|
153
|
+
view.rerender(
|
|
154
|
+
<UserPermissionProvider>
|
|
155
|
+
<div>Protected workspace</div>
|
|
156
|
+
</UserPermissionProvider>,
|
|
157
|
+
);
|
|
158
|
+
await advance(0);
|
|
159
|
+
await act(async () => resolveOld([]));
|
|
160
|
+
expect(fetch.mock.calls[0][0]?.signal?.aborted).toBe(true);
|
|
161
|
+
expect(screen.queryByText('Protected workspace')).toBeNull();
|
|
162
|
+
expect(screen.getByRole('alert').textContent).toContain('Access Denied');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('uses permissions embedded in the token without fetching mappings', () => {
|
|
166
|
+
session.authToken = { ...session.authToken, permissions: [] };
|
|
167
|
+
const fetch = vi.spyOn(session.client.iam.roles, 'listSystem');
|
|
168
|
+
renderProvider();
|
|
169
|
+
expect(screen.getByText('Protected workspace')).toBeTruthy();
|
|
170
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type AuthTokenPayload, type Permission, PrincipalType, type SystemRoleDefinition } from '@vertesia/common';
|
|
2
|
-
import {
|
|
2
|
+
import { Button, errorMessage, Spinner } from '@vertesia/ui/core';
|
|
3
3
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
4
4
|
import { useUserSession } from '@vertesia/ui/session';
|
|
5
5
|
import { createContext, useContext, useMemo } from 'react';
|
|
6
6
|
import { isAnyOf } from './helpers';
|
|
7
|
+
import { roleMappingsErrorStatus, useRoleMappings } from './useRoleMappings';
|
|
7
8
|
|
|
8
9
|
type ListRolesResponse = SystemRoleDefinition[];
|
|
9
10
|
|
|
@@ -68,35 +69,81 @@ export function useUserPermissions() {
|
|
|
68
69
|
|
|
69
70
|
interface UserPermissionProviderProps {
|
|
70
71
|
children: React.ReactNode;
|
|
72
|
+
loadingIcon?: React.ReactNode;
|
|
71
73
|
}
|
|
72
|
-
export function UserPermissionProvider({ children }: UserPermissionProviderProps) {
|
|
74
|
+
export function UserPermissionProvider({ children, loadingIcon }: UserPermissionProviderProps) {
|
|
73
75
|
const { t } = useUITranslation();
|
|
74
76
|
const session = useUserSession();
|
|
75
77
|
const authToken = session.authToken;
|
|
76
|
-
const
|
|
77
|
-
const { data, error, isLoading } = useFetch<ListRolesResponse | undefined>(() => {
|
|
78
|
-
if (shouldFetchRoleMappings) {
|
|
79
|
-
return session.client.iam.roles.listSystem();
|
|
80
|
-
}
|
|
81
|
-
return Promise.resolve(undefined);
|
|
82
|
-
}, [session.client, authToken, shouldFetchRoleMappings]);
|
|
78
|
+
const { state, retry } = useRoleMappings(session.client, authToken);
|
|
83
79
|
|
|
84
80
|
const perms = useMemo(() => {
|
|
85
|
-
if (authToken)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
return undefined;
|
|
81
|
+
if (!authToken) return undefined;
|
|
82
|
+
if (authToken.permissions) {
|
|
83
|
+
return new UserPermissions(authToken);
|
|
84
|
+
}
|
|
85
|
+
if (state.status === 'ready') {
|
|
86
|
+
return new UserPermissions(authToken, state.roles);
|
|
94
87
|
}
|
|
95
88
|
return undefined;
|
|
96
|
-
}, [authToken,
|
|
89
|
+
}, [authToken, state]);
|
|
97
90
|
|
|
98
|
-
if (
|
|
99
|
-
|
|
91
|
+
if (authToken && !perms) {
|
|
92
|
+
const failed = state.status === 'error';
|
|
93
|
+
const status = failed ? roleMappingsErrorStatus(state.error) : undefined;
|
|
94
|
+
const needsSignIn = status === 401;
|
|
95
|
+
const denied = status === 403;
|
|
96
|
+
const title = needsSignIn
|
|
97
|
+
? t('auth.recovery.credential.title')
|
|
98
|
+
: denied
|
|
99
|
+
? t('shell.accessDenied')
|
|
100
|
+
: failed
|
|
101
|
+
? t('permissions.connectionFailed')
|
|
102
|
+
: t('permissions.connecting');
|
|
103
|
+
return (
|
|
104
|
+
<div className="flex min-h-dvh items-center justify-center bg-background px-6 text-foreground">
|
|
105
|
+
<div className="w-full max-w-md space-y-6 text-center">
|
|
106
|
+
<div aria-hidden="true" className="flex justify-center">
|
|
107
|
+
{loadingIcon || (!failed && <Spinner size="2xl" className="text-primary" />)}
|
|
108
|
+
</div>
|
|
109
|
+
<div
|
|
110
|
+
role={failed ? 'alert' : 'status'}
|
|
111
|
+
aria-live={failed ? 'assertive' : 'polite'}
|
|
112
|
+
className="space-y-2"
|
|
113
|
+
>
|
|
114
|
+
<h1 className="text-xl font-semibold">{title}</h1>
|
|
115
|
+
<p className="text-muted">
|
|
116
|
+
{needsSignIn
|
|
117
|
+
? t('auth.recovery.credential.body')
|
|
118
|
+
: denied
|
|
119
|
+
? t('permissions.accessDenied')
|
|
120
|
+
: failed
|
|
121
|
+
? t('permissions.tryAgainLater')
|
|
122
|
+
: state.status === 'retrying'
|
|
123
|
+
? t('permissions.retrying')
|
|
124
|
+
: t('permissions.loadingPermissions')}
|
|
125
|
+
</p>
|
|
126
|
+
</div>
|
|
127
|
+
{failed && (
|
|
128
|
+
<>
|
|
129
|
+
<Button variant="outline" onClick={needsSignIn || denied ? () => session.signOut() : retry}>
|
|
130
|
+
{needsSignIn || denied
|
|
131
|
+
? t('auth.recovery.useDifferentAccount')
|
|
132
|
+
: t('auth.recovery.tryAgain')}
|
|
133
|
+
</Button>
|
|
134
|
+
{state.error != null && (
|
|
135
|
+
<details className="text-start text-sm text-muted">
|
|
136
|
+
<summary className="cursor-pointer">{t('auth.recovery.technicalDetails')}</summary>
|
|
137
|
+
<pre className="mt-2 max-h-48 overflow-auto whitespace-pre-wrap wrap-break-word">
|
|
138
|
+
{errorMessage(state.error)}
|
|
139
|
+
</pre>
|
|
140
|
+
</details>
|
|
141
|
+
)}
|
|
142
|
+
</>
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
100
147
|
}
|
|
101
148
|
|
|
102
149
|
return perms && <UserPermissionsContext.Provider value={perms}>{children}</UserPermissionsContext.Provider>;
|