@vertesia/ui 1.5.0-dev.20260807.073259Z → 1.5.0-dev.20260901.005903Z

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.
Files changed (502) hide show
  1. package/README.md +1 -7
  2. package/lib/core/components/FormItem.d.ts.map +1 -1
  3. package/lib/core/components/FormItem.js +2 -3
  4. package/lib/core/components/FormItem.js.map +1 -1
  5. package/lib/core/components/InfoTip.d.ts +20 -0
  6. package/lib/core/components/InfoTip.d.ts.map +1 -0
  7. package/lib/core/components/InfoTip.js +18 -0
  8. package/lib/core/components/InfoTip.js.map +1 -0
  9. package/lib/core/components/index.d.ts +1 -0
  10. package/lib/core/components/index.d.ts.map +1 -1
  11. package/lib/core/components/index.js +1 -0
  12. package/lib/core/components/index.js.map +1 -1
  13. package/lib/core/components/shadcn/Panel.d.ts.map +1 -1
  14. package/lib/core/components/shadcn/Panel.js +3 -3
  15. package/lib/core/components/shadcn/Panel.js.map +1 -1
  16. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +1 -1
  17. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -1
  18. package/lib/core/components/shadcn/filters/filter/dateFilter.d.ts.map +1 -1
  19. package/lib/core/components/shadcn/filters/filter/dateFilter.js +1 -1
  20. package/lib/core/components/shadcn/filters/filter/dateFilter.js.map +1 -1
  21. package/lib/core/components/shadcn/filters/filters.d.ts.map +1 -1
  22. package/lib/core/components/shadcn/filters/filters.js +1 -1
  23. package/lib/core/components/shadcn/filters/filters.js.map +1 -1
  24. package/lib/core/components/shadcn/index.d.ts +1 -0
  25. package/lib/core/components/shadcn/index.d.ts.map +1 -1
  26. package/lib/core/components/shadcn/index.js +1 -0
  27. package/lib/core/components/shadcn/index.js.map +1 -1
  28. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  29. package/lib/core/components/shadcn/modal/dialog.js +1 -3
  30. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  31. package/lib/core/components/shadcn/overflowTabs.d.ts +59 -0
  32. package/lib/core/components/shadcn/overflowTabs.d.ts.map +1 -0
  33. package/lib/core/components/shadcn/overflowTabs.js +173 -0
  34. package/lib/core/components/shadcn/overflowTabs.js.map +1 -0
  35. package/lib/core/components/shadcn/selectBox.js +2 -2
  36. package/lib/core/components/shadcn/selectBox.js.map +1 -1
  37. package/lib/core/components/shadcn/theme/ThemeProvider.d.ts +3 -1
  38. package/lib/core/components/shadcn/theme/ThemeProvider.d.ts.map +1 -1
  39. package/lib/core/components/shadcn/theme/ThemeProvider.js +8 -9
  40. package/lib/core/components/shadcn/theme/ThemeProvider.js.map +1 -1
  41. package/lib/core/utils/dayjs.d.ts +12 -0
  42. package/lib/core/utils/dayjs.d.ts.map +1 -0
  43. package/lib/core/utils/dayjs.js +16 -0
  44. package/lib/core/utils/dayjs.js.map +1 -0
  45. package/lib/env/index.d.ts +17 -0
  46. package/lib/env/index.d.ts.map +1 -1
  47. package/lib/env/index.js +18 -1
  48. package/lib/env/index.js.map +1 -1
  49. package/lib/features/agent/PayloadBuilder.d.ts +1 -0
  50. package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
  51. package/lib/features/agent/PayloadBuilder.js +22 -5
  52. package/lib/features/agent/PayloadBuilder.js.map +1 -1
  53. package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
  54. package/lib/features/agent/chat/AgentRightPanel.js +3 -135
  55. package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
  56. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  57. package/lib/features/agent/chat/ArtifactsTab.js +1 -1
  58. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  59. package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
  60. package/lib/features/agent/chat/AskUserWidget.js +19 -4
  61. package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
  62. package/lib/features/agent/chat/ModernAgentConversation.d.ts +6 -0
  63. package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  64. package/lib/features/agent/chat/ModernAgentConversation.js +99 -29
  65. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  66. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
  67. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +10 -9
  68. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
  69. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  70. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +5 -8
  71. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  72. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
  73. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +45 -4
  74. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
  75. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +1 -1
  76. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
  77. package/lib/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  78. package/lib/features/agent/chat/ModernAgentOutput/Header.js +3 -3
  79. package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  80. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  81. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +1 -1
  82. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  83. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
  84. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js +1 -1
  85. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
  86. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +1 -1
  87. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  88. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.d.ts.map +1 -1
  89. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +9 -121
  90. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  91. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +6 -0
  92. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  93. package/lib/features/agent/chat/ModernAgentOutput/utils.js +19 -11
  94. package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  95. package/lib/features/agent/chat/VegaLiteChart.d.ts.map +1 -1
  96. package/lib/features/agent/chat/VegaLiteChart.js +11 -3
  97. package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
  98. package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
  99. package/lib/features/agent/chat/hooks/useAgentStream.js +3 -0
  100. package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
  101. package/lib/features/document-viewer/UniversalDocumentViewer.d.ts.map +1 -1
  102. package/lib/features/document-viewer/UniversalDocumentViewer.js +1 -1
  103. package/lib/features/document-viewer/UniversalDocumentViewer.js.map +1 -1
  104. package/lib/features/facets/AgentRunnerFacetsNav.d.ts +14 -2
  105. package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
  106. package/lib/features/facets/AgentRunnerFacetsNav.js +20 -2
  107. package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
  108. package/lib/features/facets/CollectionsFacetsNav.d.ts +3 -3
  109. package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
  110. package/lib/features/facets/CollectionsFacetsNav.js +6 -1
  111. package/lib/features/facets/CollectionsFacetsNav.js.map +1 -1
  112. package/lib/features/facets/DocumentsFacetsNav.d.ts +3 -3
  113. package/lib/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
  114. package/lib/features/facets/DocumentsFacetsNav.js +20 -8
  115. package/lib/features/facets/DocumentsFacetsNav.js.map +1 -1
  116. package/lib/features/facets/InteractionsFacetsNav.d.ts +3 -3
  117. package/lib/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  118. package/lib/features/facets/InteractionsFacetsNav.js +11 -1
  119. package/lib/features/facets/InteractionsFacetsNav.js.map +1 -1
  120. package/lib/features/facets/PromptsFacetsNav.d.ts +3 -3
  121. package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
  122. package/lib/features/facets/PromptsFacetsNav.js +6 -1
  123. package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
  124. package/lib/features/facets/RunsFacetsNav.d.ts +4 -14
  125. package/lib/features/facets/RunsFacetsNav.d.ts.map +1 -1
  126. package/lib/features/facets/RunsFacetsNav.js +26 -15
  127. package/lib/features/facets/RunsFacetsNav.js.map +1 -1
  128. package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts +4 -3
  129. package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
  130. package/lib/features/facets/WorkflowExecutionsFacetsNav.js +18 -10
  131. package/lib/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -1
  132. package/lib/features/facets/index.d.ts +1 -1
  133. package/lib/features/facets/index.d.ts.map +1 -1
  134. package/lib/features/facets/index.js.map +1 -1
  135. package/lib/features/facets/utils/SearchInterface.d.ts +4 -3
  136. package/lib/features/facets/utils/SearchInterface.d.ts.map +1 -1
  137. package/lib/features/facets/utils/SearchInterface.js +4 -0
  138. package/lib/features/facets/utils/SearchInterface.js.map +1 -1
  139. package/lib/features/layout/GenericPageNavHeader.d.ts +8 -1
  140. package/lib/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  141. package/lib/features/layout/GenericPageNavHeader.js +9 -1
  142. package/lib/features/layout/GenericPageNavHeader.js.map +1 -1
  143. package/lib/features/magic-pdf/DownloadPopover.d.ts +3 -2
  144. package/lib/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
  145. package/lib/features/magic-pdf/DownloadPopover.js.map +1 -1
  146. package/lib/features/magic-pdf/GroundedExtractionView.d.ts.map +1 -1
  147. package/lib/features/magic-pdf/GroundedExtractionView.js +51 -64
  148. package/lib/features/magic-pdf/GroundedExtractionView.js.map +1 -1
  149. package/lib/features/oauth/McpConnectionsButton.d.ts +1 -1
  150. package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -1
  151. package/lib/features/oauth/McpConnectionsButton.js +2 -2
  152. package/lib/features/oauth/McpConnectionsButton.js.map +1 -1
  153. package/lib/features/oauth/McpConnectionsDialog.d.ts +1 -1
  154. package/lib/features/oauth/McpConnectionsDialog.js +2 -2
  155. package/lib/features/oauth/McpConnectionsDialog.js.map +1 -1
  156. package/lib/features/oauth/useMcpConnections.d.ts +4 -5
  157. package/lib/features/oauth/useMcpConnections.d.ts.map +1 -1
  158. package/lib/features/oauth/useMcpConnections.js +20 -4
  159. package/lib/features/oauth/useMcpConnections.js.map +1 -1
  160. package/lib/features/pdf-viewer/PdfPageRenderer.d.ts.map +1 -1
  161. package/lib/features/pdf-viewer/PdfPageRenderer.js +9 -11
  162. package/lib/features/pdf-viewer/PdfPageRenderer.js.map +1 -1
  163. package/lib/features/pdf-viewer/lazyReactPdf.d.ts +10 -0
  164. package/lib/features/pdf-viewer/lazyReactPdf.d.ts.map +1 -0
  165. package/lib/features/pdf-viewer/lazyReactPdf.js +25 -0
  166. package/lib/features/pdf-viewer/lazyReactPdf.js.map +1 -0
  167. package/lib/features/store/collections/CollectionsTable.d.ts.map +1 -1
  168. package/lib/features/store/collections/CollectionsTable.js +1 -3
  169. package/lib/features/store/collections/CollectionsTable.js.map +1 -1
  170. package/lib/features/store/collections/EditCollectionView.js +1 -1
  171. package/lib/features/store/collections/EditCollectionView.js.map +1 -1
  172. package/lib/features/store/objects/ExportPropertiesModal.d.ts +3 -1
  173. package/lib/features/store/objects/ExportPropertiesModal.d.ts.map +1 -1
  174. package/lib/features/store/objects/ExportPropertiesModal.js +5 -5
  175. package/lib/features/store/objects/ExportPropertiesModal.js.map +1 -1
  176. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  177. package/lib/features/store/objects/components/ContentOverview.js +4 -10
  178. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  179. package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
  180. package/lib/features/store/objects/components/TextEditorPanel.js +8 -3
  181. package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
  182. package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
  183. package/lib/features/store/objects/layout/renderers.js +1 -5
  184. package/lib/features/store/objects/layout/renderers.js.map +1 -1
  185. package/lib/features/store/objects/search/DocumentSearchContext.d.ts +44 -62
  186. package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  187. package/lib/features/store/objects/search/DocumentSearchContext.js +47 -2
  188. package/lib/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  189. package/lib/features/store/objects/selection/actions/DeleteObjectsAction.d.ts.map +1 -1
  190. package/lib/features/store/objects/selection/actions/DeleteObjectsAction.js +5 -0
  191. package/lib/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
  192. package/lib/features/store/objects/upload/DocumentUploadModal.d.ts +6 -1
  193. package/lib/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  194. package/lib/features/store/objects/upload/DocumentUploadModal.js +4 -3
  195. package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  196. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
  197. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js +2 -2
  198. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
  199. package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
  200. package/lib/features/store/types/ContentObjectTypesTable.js +1 -3
  201. package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
  202. package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
  203. package/lib/features/store/types/IntakePolicyEditor.js +12 -2
  204. package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
  205. package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
  206. package/lib/features/store/types/IntakePolicyForm.js +15 -15
  207. package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
  208. package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
  209. package/lib/features/store/types/ObjectSchemaEditor.js +6 -2
  210. package/lib/features/store/types/ObjectSchemaEditor.js.map +1 -1
  211. package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
  212. package/lib/features/store/types/TableLayoutEditor.js +2 -0
  213. package/lib/features/store/types/TableLayoutEditor.js.map +1 -1
  214. package/lib/features/store/types/TypeRegistry.d.ts +282 -0
  215. package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
  216. package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +281 -0
  217. package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
  218. package/lib/features/user/UserInfo.d.ts.map +1 -1
  219. package/lib/features/user/UserInfo.js +2 -4
  220. package/lib/features/user/UserInfo.js.map +1 -1
  221. package/lib/features/views/ViewActions.d.ts +32 -0
  222. package/lib/features/views/ViewActions.d.ts.map +1 -0
  223. package/lib/features/views/ViewActions.js +186 -0
  224. package/lib/features/views/ViewActions.js.map +1 -0
  225. package/lib/features/views/ViewDropTarget.d.ts +15 -0
  226. package/lib/features/views/ViewDropTarget.d.ts.map +1 -0
  227. package/lib/features/views/ViewDropTarget.js +79 -0
  228. package/lib/features/views/ViewDropTarget.js.map +1 -0
  229. package/lib/features/views/ViewExperience.d.ts +3 -2
  230. package/lib/features/views/ViewExperience.d.ts.map +1 -1
  231. package/lib/features/views/ViewExperience.js +103 -12
  232. package/lib/features/views/ViewExperience.js.map +1 -1
  233. package/lib/features/views/ViewNavigation.d.ts +1 -1
  234. package/lib/features/views/ViewNavigation.d.ts.map +1 -1
  235. package/lib/features/views/ViewNavigation.js +14 -5
  236. package/lib/features/views/ViewNavigation.js.map +1 -1
  237. package/lib/features/views/ViewResults.d.ts +1 -1
  238. package/lib/features/views/ViewResults.d.ts.map +1 -1
  239. package/lib/features/views/ViewResults.js +124 -34
  240. package/lib/features/views/ViewResults.js.map +1 -1
  241. package/lib/features/views/index.d.ts +1 -0
  242. package/lib/features/views/index.d.ts.map +1 -1
  243. package/lib/features/views/index.js +1 -0
  244. package/lib/features/views/index.js.map +1 -1
  245. package/lib/features/views/types.d.ts +46 -1
  246. package/lib/features/views/types.d.ts.map +1 -1
  247. package/lib/features/views/viewState.d.ts.map +1 -1
  248. package/lib/features/views/viewState.js +34 -0
  249. package/lib/features/views/viewState.js.map +1 -1
  250. package/lib/i18n/LanguageProvider.d.ts +3 -1
  251. package/lib/i18n/LanguageProvider.d.ts.map +1 -1
  252. package/lib/i18n/LanguageProvider.js +9 -7
  253. package/lib/i18n/LanguageProvider.js.map +1 -1
  254. package/lib/i18n/instance.d.ts +2 -0
  255. package/lib/i18n/instance.d.ts.map +1 -1
  256. package/lib/i18n/instance.js +45 -26
  257. package/lib/i18n/instance.js.map +1 -1
  258. package/lib/i18n/locales/ar.json +296 -15
  259. package/lib/i18n/locales/de.json +294 -13
  260. package/lib/i18n/locales/en.json +65 -4
  261. package/lib/i18n/locales/es.json +295 -14
  262. package/lib/i18n/locales/fr.json +294 -13
  263. package/lib/i18n/locales/it.json +294 -13
  264. package/lib/i18n/locales/ja.json +292 -10
  265. package/lib/i18n/locales/ko.json +292 -10
  266. package/lib/i18n/locales/pt.json +294 -13
  267. package/lib/i18n/locales/ru.json +291 -10
  268. package/lib/i18n/locales/tr.json +291 -10
  269. package/lib/i18n/locales/zh-TW.json +292 -10
  270. package/lib/i18n/locales/zh.json +292 -10
  271. package/lib/router/RouteComponent.d.ts +8 -0
  272. package/lib/router/RouteComponent.d.ts.map +1 -1
  273. package/lib/router/RouteComponent.js +41 -9
  274. package/lib/router/RouteComponent.js.map +1 -1
  275. package/lib/session/UserSessionProvider.d.ts.map +1 -1
  276. package/lib/session/UserSessionProvider.js +20 -29
  277. package/lib/session/UserSessionProvider.js.map +1 -1
  278. package/lib/session/auth/composable.d.ts.map +1 -1
  279. package/lib/session/auth/composable.js +25 -19
  280. package/lib/session/auth/composable.js.map +1 -1
  281. package/lib/session/auth/domainRouting.d.ts +11 -0
  282. package/lib/session/auth/domainRouting.d.ts.map +1 -1
  283. package/lib/session/auth/domainRouting.js +13 -0
  284. package/lib/session/auth/domainRouting.js.map +1 -1
  285. package/lib/session/auth/firebase.js +1 -1
  286. package/lib/session/auth/firebase.js.map +1 -1
  287. package/lib/session/useUXTracking.d.ts.map +1 -1
  288. package/lib/session/useUXTracking.js +6 -1
  289. package/lib/session/useUXTracking.js.map +1 -1
  290. package/lib/shell/VertesiaShell.d.ts.map +1 -1
  291. package/lib/shell/VertesiaShell.js +2 -1
  292. package/lib/shell/VertesiaShell.js.map +1 -1
  293. package/lib/shell/apps/AppInstallationProvider.d.ts +4 -2
  294. package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
  295. package/lib/shell/apps/IframeAppContextSync.d.ts +3 -0
  296. package/lib/shell/apps/IframeAppContextSync.d.ts.map +1 -0
  297. package/lib/shell/apps/IframeAppContextSync.js +95 -0
  298. package/lib/shell/apps/IframeAppContextSync.js.map +1 -0
  299. package/lib/shell/apps/iframe-auth.d.ts +55 -0
  300. package/lib/shell/apps/iframe-auth.d.ts.map +1 -0
  301. package/lib/shell/apps/iframe-auth.js +154 -0
  302. package/lib/shell/apps/iframe-auth.js.map +1 -0
  303. package/lib/shell/apps/index.d.ts +2 -0
  304. package/lib/shell/apps/index.d.ts.map +1 -1
  305. package/lib/shell/apps/index.js +2 -0
  306. package/lib/shell/apps/index.js.map +1 -1
  307. package/lib/vertesia-ui-core.js +199 -4
  308. package/lib/vertesia-ui-core.js.map +1 -1
  309. package/lib/vertesia-ui-env.js +1 -1
  310. package/lib/vertesia-ui-env.js.map +1 -1
  311. package/lib/vertesia-ui-features.js +975 -35
  312. package/lib/vertesia-ui-features.js.map +1 -1
  313. package/lib/vertesia-ui-i18n.BJBGsq-8.chunk.js +5 -0
  314. package/lib/vertesia-ui-i18n.BJBGsq-8.chunk.js.map +1 -0
  315. package/lib/vertesia-ui-i18n.BY5YG5cX.chunk.js +5 -0
  316. package/lib/vertesia-ui-i18n.BY5YG5cX.chunk.js.map +1 -0
  317. package/lib/vertesia-ui-i18n.Bd5_1BXO.chunk.js +5 -0
  318. package/lib/vertesia-ui-i18n.Bd5_1BXO.chunk.js.map +1 -0
  319. package/lib/vertesia-ui-i18n.Bvwej2HH.chunk.js +5 -0
  320. package/lib/vertesia-ui-i18n.Bvwej2HH.chunk.js.map +1 -0
  321. package/lib/vertesia-ui-i18n.CMT3f4gf.chunk.js +5 -0
  322. package/lib/vertesia-ui-i18n.CMT3f4gf.chunk.js.map +1 -0
  323. package/lib/vertesia-ui-i18n.D56DNPJW.chunk.js +5 -0
  324. package/lib/vertesia-ui-i18n.D56DNPJW.chunk.js.map +1 -0
  325. package/lib/vertesia-ui-i18n.DDzKLNx6.chunk.js +5 -0
  326. package/lib/vertesia-ui-i18n.DDzKLNx6.chunk.js.map +1 -0
  327. package/lib/vertesia-ui-i18n.D_Am1LpF.chunk.js +5 -0
  328. package/lib/vertesia-ui-i18n.D_Am1LpF.chunk.js.map +1 -0
  329. package/lib/vertesia-ui-i18n.DrZizgGV.chunk.js +5 -0
  330. package/lib/vertesia-ui-i18n.DrZizgGV.chunk.js.map +1 -0
  331. package/lib/vertesia-ui-i18n.DwHsq86z.chunk.js +5 -0
  332. package/lib/vertesia-ui-i18n.DwHsq86z.chunk.js.map +1 -0
  333. package/lib/vertesia-ui-i18n.PLpo0Bbz.chunk.js +5 -0
  334. package/lib/vertesia-ui-i18n.PLpo0Bbz.chunk.js.map +1 -0
  335. package/lib/vertesia-ui-i18n.js +2 -38
  336. package/lib/vertesia-ui-i18n.js.map +1 -1
  337. package/lib/vertesia-ui-i18n.xVbXALqz.chunk.js +5 -0
  338. package/lib/vertesia-ui-i18n.xVbXALqz.chunk.js.map +1 -0
  339. package/lib/vertesia-ui-layout.js +80 -1
  340. package/lib/vertesia-ui-layout.js.map +1 -1
  341. package/lib/vertesia-ui-rich-text.js +278 -4
  342. package/lib/vertesia-ui-rich-text.js.map +1 -1
  343. package/lib/vertesia-ui-router.js +1 -1
  344. package/lib/vertesia-ui-router.js.map +1 -1
  345. package/lib/vertesia-ui-session.js +1 -1
  346. package/lib/vertesia-ui-session.js.map +1 -1
  347. package/lib/vertesia-ui-shell.js +118 -1
  348. package/lib/vertesia-ui-shell.js.map +1 -1
  349. package/lib/vertesia-ui-widgets.js +336 -20
  350. package/lib/vertesia-ui-widgets.js.map +1 -1
  351. package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  352. package/lib/widgets/markdown/MarkdownRenderer.js +43 -2
  353. package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
  354. package/lib/widgets/markdown/MermaidDiagram.d.ts.map +1 -1
  355. package/lib/widgets/markdown/MermaidDiagram.js +35 -22
  356. package/lib/widgets/markdown/MermaidDiagram.js.map +1 -1
  357. package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  358. package/lib/widgets/monacoEditor/MonacoEditor.js +14 -10
  359. package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  360. package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
  361. package/package.json +24 -29
  362. package/src/core/components/FormItem.tsx +2 -5
  363. package/src/core/components/InfoTip.test.tsx +33 -0
  364. package/src/core/components/InfoTip.tsx +32 -0
  365. package/src/core/components/index.ts +1 -0
  366. package/src/core/components/shadcn/Panel.tsx +3 -7
  367. package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +1 -1
  368. package/src/core/components/shadcn/filters/filter/dateFilter.tsx +1 -1
  369. package/src/core/components/shadcn/filters/filters.tsx +1 -1
  370. package/src/core/components/shadcn/index.ts +1 -0
  371. package/src/core/components/shadcn/modal/dialog.test.tsx +35 -0
  372. package/src/core/components/shadcn/modal/dialog.tsx +0 -4
  373. package/src/core/components/shadcn/overflowTabs.tsx +320 -0
  374. package/src/core/components/shadcn/selectBox.tsx +2 -2
  375. package/src/core/components/shadcn/theme/ThemeProvider.tsx +10 -9
  376. package/src/core/utils/dayjs.ts +17 -0
  377. package/src/css/base.css +78 -0
  378. package/src/env/index.test.ts +94 -0
  379. package/src/env/index.ts +36 -1
  380. package/src/features/agent/PayloadBuilder.test.ts +68 -0
  381. package/src/features/agent/PayloadBuilder.tsx +28 -4
  382. package/src/features/agent/chat/AgentRightPanel.tsx +2 -252
  383. package/src/features/agent/chat/ArtifactsTab.tsx +1 -0
  384. package/src/features/agent/chat/AskUserWidget.test.tsx +20 -1
  385. package/src/features/agent/chat/AskUserWidget.tsx +22 -6
  386. package/src/features/agent/chat/ModernAgentConversation.test.tsx +160 -0
  387. package/src/features/agent/chat/ModernAgentConversation.tsx +111 -31
  388. package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +86 -67
  389. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +90 -7
  390. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +4 -6
  391. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +103 -1
  392. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +50 -4
  393. package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +1 -1
  394. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +18 -1
  395. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +1 -1
  396. package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +1 -1
  397. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +1 -1
  398. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +37 -167
  399. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +94 -0
  400. package/src/features/agent/chat/ModernAgentOutput/utils.ts +19 -10
  401. package/src/features/agent/chat/VegaLiteChart.tsx +32 -14
  402. package/src/features/agent/chat/hooks/useAgentStream.test.tsx +18 -0
  403. package/src/features/agent/chat/hooks/useAgentStream.ts +3 -0
  404. package/src/features/document-viewer/UniversalDocumentViewer.tsx +1 -1
  405. package/src/features/facets/AgentRunnerFacetsNav.tsx +44 -4
  406. package/src/features/facets/CollectionsFacetsNav.tsx +15 -4
  407. package/src/features/facets/DocumentsFacetsNav.tsx +25 -8
  408. package/src/features/facets/FacetQueryHandlers.test.ts +84 -0
  409. package/src/features/facets/InteractionsFacetsNav.tsx +20 -4
  410. package/src/features/facets/PromptsFacetsNav.tsx +15 -4
  411. package/src/features/facets/RunsFacetsNav.test.ts +59 -0
  412. package/src/features/facets/RunsFacetsNav.tsx +40 -30
  413. package/src/features/facets/WorkflowExecutionsFacetsNav.test.ts +57 -0
  414. package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +36 -16
  415. package/src/features/facets/index.ts +1 -0
  416. package/src/features/facets/utils/SearchInterface.tsx +12 -3
  417. package/src/features/layout/GenericPageNavHeader.tsx +16 -0
  418. package/src/features/magic-pdf/DownloadPopover.tsx +1 -2
  419. package/src/features/magic-pdf/GroundedExtractionView.test.tsx +7 -1
  420. package/src/features/magic-pdf/GroundedExtractionView.tsx +162 -242
  421. package/src/features/oauth/McpConnectionsButton.test.tsx +18 -1
  422. package/src/features/oauth/McpConnectionsButton.tsx +6 -2
  423. package/src/features/oauth/McpConnectionsDialog.tsx +3 -3
  424. package/src/features/oauth/useMcpConnections.test.ts +1 -0
  425. package/src/features/oauth/useMcpConnections.ts +24 -7
  426. package/src/features/pdf-viewer/PdfPageRenderer.tsx +76 -71
  427. package/src/features/pdf-viewer/lazyReactPdf.ts +33 -0
  428. package/src/features/store/collections/CollectionsTable.tsx +1 -4
  429. package/src/features/store/collections/EditCollectionView.tsx +1 -1
  430. package/src/features/store/objects/ExportPropertiesModal.tsx +25 -16
  431. package/src/features/store/objects/components/ContentOverview.tsx +2 -28
  432. package/src/features/store/objects/components/TextEditorPanel.tsx +13 -3
  433. package/src/features/store/objects/layout/renderers.tsx +1 -6
  434. package/src/features/store/objects/search/DocumentSearchContext.test.ts +45 -0
  435. package/src/features/store/objects/search/DocumentSearchContext.ts +54 -4
  436. package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +5 -0
  437. package/src/features/store/objects/upload/DocumentUploadModal.tsx +10 -3
  438. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +15 -6
  439. package/src/features/store/types/ContentObjectTypesTable.tsx +1 -4
  440. package/src/features/store/types/IntakePolicyEditor.tsx +14 -5
  441. package/src/features/store/types/IntakePolicyForm.tsx +120 -20
  442. package/src/features/store/types/ObjectSchemaEditor.tsx +6 -2
  443. package/src/features/store/types/TableLayoutEditor.tsx +2 -0
  444. package/src/features/user/UserInfo.test.tsx +10 -0
  445. package/src/features/user/UserInfo.tsx +2 -7
  446. package/src/features/views/ViewActions.test.tsx +80 -0
  447. package/src/features/views/ViewActions.tsx +352 -0
  448. package/src/features/views/ViewDropTarget.test.tsx +150 -0
  449. package/src/features/views/ViewDropTarget.tsx +140 -0
  450. package/src/features/views/ViewExperience.test.tsx +72 -0
  451. package/src/features/views/ViewExperience.tsx +189 -22
  452. package/src/features/views/ViewMedia.test.tsx +180 -0
  453. package/src/features/views/ViewNavigation.test.tsx +42 -0
  454. package/src/features/views/ViewNavigation.tsx +43 -5
  455. package/src/features/views/ViewResults.tsx +243 -26
  456. package/src/features/views/index.ts +1 -0
  457. package/src/features/views/types.ts +50 -0
  458. package/src/features/views/viewState.test.ts +7 -1
  459. package/src/features/views/viewState.ts +32 -0
  460. package/src/i18n/LanguageProvider.tsx +15 -8
  461. package/src/i18n/instance.test.ts +30 -0
  462. package/src/i18n/instance.ts +67 -40
  463. package/src/i18n/locales/ar.json +1192 -911
  464. package/src/i18n/locales/de.json +1148 -867
  465. package/src/i18n/locales/en.json +65 -4
  466. package/src/i18n/locales/es.json +1159 -878
  467. package/src/i18n/locales/fr.json +1159 -878
  468. package/src/i18n/locales/it.json +1159 -878
  469. package/src/i18n/locales/ja.json +1148 -866
  470. package/src/i18n/locales/ko.json +1148 -866
  471. package/src/i18n/locales/pt.json +1159 -878
  472. package/src/i18n/locales/ru.json +1170 -889
  473. package/src/i18n/locales/tr.json +1148 -867
  474. package/src/i18n/locales/zh-TW.json +1148 -866
  475. package/src/i18n/locales/zh.json +1148 -866
  476. package/src/i18n/rtl.test.ts +16 -7
  477. package/src/rich-text/VertesiaRichTextEditor.test.tsx +33 -1
  478. package/src/router/RouteComponent.test.tsx +139 -0
  479. package/src/router/RouteComponent.tsx +54 -9
  480. package/src/session/UserSessionProvider.tsx +20 -31
  481. package/src/session/auth/composable.scope.test.ts +1 -1
  482. package/src/session/auth/composable.test.ts +61 -1
  483. package/src/session/auth/composable.ts +29 -23
  484. package/src/session/auth/domainRouting.test.ts +24 -1
  485. package/src/session/auth/domainRouting.ts +29 -0
  486. package/src/session/auth/firebase.ts +1 -1
  487. package/src/session/useUXTracking.tsx +6 -1
  488. package/src/shell/VertesiaShell.tsx +2 -0
  489. package/src/shell/apps/IframeAppContextSync.test.tsx +196 -0
  490. package/src/shell/apps/IframeAppContextSync.tsx +101 -0
  491. package/src/shell/apps/iframe-auth.test.ts +118 -0
  492. package/src/shell/apps/iframe-auth.ts +193 -0
  493. package/src/shell/apps/index.ts +2 -0
  494. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +12 -3
  495. package/src/widgets/markdown/MarkdownRenderer.tsx +50 -2
  496. package/src/widgets/markdown/MermaidDiagram.tsx +38 -22
  497. package/src/widgets/monacoEditor/MonacoEditor.tsx +27 -20
  498. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts +0 -25
  499. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts.map +0 -1
  500. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js +0 -42
  501. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js.map +0 -1
  502. package/src/features/magic-pdf/GroundedExtractionAssistantPanel.tsx +0 -86
@@ -92,6 +92,9 @@ function isVertesiaIssuedToken(token: string | undefined): token is string {
92
92
 
93
93
  function canUseVertesiaTokenDirectly(token: string, accountId?: string, projectId?: string): boolean {
94
94
  const decoded = decodeToken(token);
95
+ if (!decoded.exp || decoded.exp <= Date.now() / 1000 + 300) {
96
+ return false;
97
+ }
95
98
  const hasAuthorizationClaims = Boolean(
96
99
  decoded.permissions?.length ||
97
100
  decoded.account_roles?.length ||
@@ -117,8 +120,7 @@ export async function fetchComposableToken(
117
120
  ttl?: number,
118
121
  retryCount = 0,
119
122
  ): Promise<string> {
120
- console.log(`Getting/refreshing composable token for account ${accountId} and project ${projectId} `);
121
- Env.logger.info('Getting/refreshing composable token', {
123
+ Env.logger.debug('Getting/refreshing composable token', {
122
124
  vertesia: {
123
125
  account_id: accountId,
124
126
  project_id: projectId,
@@ -128,14 +130,12 @@ export async function fetchComposableToken(
128
130
 
129
131
  const idToken = await getIdToken(); //get from firebase
130
132
  if (!idToken) {
131
- console.log('No id token found - using cookie auth');
132
133
  throw new Error('No id token found');
133
134
  }
134
135
 
135
136
  // Use STS endpoint - either configured or default to sts.vertesia.io
136
137
  const stsEndpoint = Env.endpoints.sts;
137
- console.log('Using STS for token generation:', stsEndpoint);
138
- Env.logger.info('Using STS for token generation', {
138
+ Env.logger.debug('Using STS for token generation', {
139
139
  vertesia: {
140
140
  account_id: accountId,
141
141
  project_id: projectId,
@@ -176,8 +176,7 @@ export async function fetchComposableToken(
176
176
 
177
177
  if (idToken && stsRes?.status === 404) {
178
178
  // User not found in token-server - call ensure-user endpoint
179
- console.log('404: User not found - calling ensure-user endpoint');
180
- Env.logger.info('404: User not found - calling ensure-user endpoint', {
179
+ Env.logger.debug('404: User not found - calling ensure-user endpoint', {
181
180
  vertesia: {
182
181
  account_id: accountId,
183
182
  project_id: projectId,
@@ -195,8 +194,7 @@ export async function fetchComposableToken(
195
194
 
196
195
  if (ensureResponse.status === 412) {
197
196
  // No invite - trigger signup
198
- console.log('412: No invite found - signup required');
199
- Env.logger.info('412: No invite found - signup required', {
197
+ Env.logger.debug('412: No invite found - signup required', {
200
198
  vertesia: {
201
199
  account_id: accountId,
202
200
  project_id: projectId,
@@ -234,8 +232,7 @@ export async function fetchComposableToken(
234
232
  }
235
233
 
236
234
  // User created/exists - retry token generation
237
- console.log('User ensured - retrying token generation');
238
- Env.logger.info('User ensured - retrying token generation', {
235
+ Env.logger.debug('User ensured - retrying token generation', {
239
236
  vertesia: {
240
237
  account_id: accountId,
241
238
  project_id: projectId,
@@ -245,8 +242,7 @@ export async function fetchComposableToken(
245
242
  }
246
243
 
247
244
  if (idToken && stsRes?.status === 412) {
248
- console.log("412: auth succeeded but user doesn't exist - signup required", stsRes?.status);
249
- Env.logger.error("412: auth succeeded but user doesn't exist - signup required", {
245
+ Env.logger.info("412: auth succeeded but user doesn't exist - signup required", {
250
246
  vertesia: {
251
247
  account_id: accountId,
252
248
  project_id: projectId,
@@ -258,7 +254,7 @@ export async function fetchComposableToken(
258
254
  Env.logger.error('No email found in id token');
259
255
  throw new Error('No email found in id token');
260
256
  }
261
- Env.logger.error('User not found', {
257
+ Env.logger.info('User not found', {
262
258
  vertesia: {
263
259
  account_id: accountId,
264
260
  project_id: projectId,
@@ -354,8 +350,7 @@ export async function fetchComposableToken(
354
350
  }
355
351
 
356
352
  const { token } = await stsRes.json();
357
- console.log('Successfully got token from STS');
358
- Env.logger.info('Successfully got token from STS');
353
+ Env.logger.debug('Successfully got token from STS');
359
354
  return token;
360
355
  } catch (error) {
361
356
  if (
@@ -460,13 +455,24 @@ export async function getComposableToken(
460
455
  if (!devAuthToken && !useInternalAuth && getFirebaseAuth().currentUser) {
461
456
  //we have a firebase user, get the token from there
462
457
  AUTH_TOKEN_RAW = await fetchComposableTokenFromFirebaseToken(selectedAccount, selectedProject);
463
- } else if (!devAuthToken && (initToken || AUTH_TOKEN_RAW)) {
464
- // we have a token already and no firebase user, refresh it
465
- AUTH_TOKEN_RAW = await fetchComposableToken(
466
- () => Promise.resolve(initToken ?? AUTH_TOKEN_RAW),
467
- selectedAccount,
468
- selectedProject,
469
- );
458
+ } else if (!devAuthToken) {
459
+ // Embedded apps can reacquire a fresh credential from their host after their cached token expires.
460
+ const refreshCredential = (await Env.authTokenProvider?.()) ?? initToken ?? AUTH_TOKEN_RAW;
461
+ if (
462
+ refreshCredential &&
463
+ isVertesiaIssuedToken(refreshCredential) &&
464
+ canUseVertesiaTokenDirectly(refreshCredential, selectedAccount, selectedProject)
465
+ ) {
466
+ AUTH_TOKEN_RAW = refreshCredential;
467
+ } else if (refreshCredential) {
468
+ AUTH_TOKEN_RAW = await fetchComposableToken(
469
+ () => Promise.resolve(refreshCredential),
470
+ selectedAccount,
471
+ selectedProject,
472
+ );
473
+ } else {
474
+ AUTH_TOKEN_RAW = undefined;
475
+ }
470
476
  } else if (devAuthToken) {
471
477
  AUTH_TOKEN_RAW = devAuthToken;
472
478
  }
@@ -1,5 +1,10 @@
1
1
  import { afterEach, describe, expect, it } from 'vitest';
2
- import { mountRootUrl, shouldRedirectToCentralAuth, shouldUseFirebaseAuth } from './domainRouting';
2
+ import {
3
+ centralAuthRedirectUrl,
4
+ mountRootUrl,
5
+ shouldRedirectToCentralAuth,
6
+ shouldUseFirebaseAuth,
7
+ } from './domainRouting';
3
8
 
4
9
  // Stub document.baseURI to simulate the served `<base href>` (deep gateway mount) or its absence.
5
10
  function setBaseURI(baseURI: string) {
@@ -30,6 +35,24 @@ describe('domainRouting', () => {
30
35
  expect(shouldRedirectToCentralAuth()).toBe(true);
31
36
  });
32
37
 
38
+ it('carries the selected account and project through central auth for a gateway-mounted app', () => {
39
+ const redirect = centralAuthRedirectUrl({
40
+ centralAuthUrl: 'https://internal-auth.vertesia.app/',
41
+ stsEndpoint: 'https://sts.example.test',
42
+ returnUrl: new URL('https://apps.example.test/tenants/t/apps/a/versions/v/app/?view=grid'),
43
+ state: 'state-1',
44
+ accountId: 'account-1',
45
+ projectId: 'project-1',
46
+ });
47
+ const returnUrl = new URL(redirect.searchParams.get('redirect_uri') || '');
48
+
49
+ expect(redirect.searchParams.get('sts')).toBe('https://sts.example.test');
50
+ expect(redirect.searchParams.get('state')).toBe('state-1');
51
+ expect(returnUrl.toString()).toBe(
52
+ 'https://apps.example.test/tenants/t/apps/a/versions/v/app/?view=grid&p=project-1&a=account-1',
53
+ );
54
+ });
55
+
33
56
  describe('mountRootUrl', () => {
34
57
  it('returns the deep gateway mount root (dropping any deep route / query / hash)', () => {
35
58
  const mount = 'https://gw.example.com/tenants/05948c_5ed5f4/apps/furniture-catalog/versions/v1/app/';
@@ -12,6 +12,35 @@ export function shouldRedirectToCentralAuth(_hostname?: string) {
12
12
  return !shouldUseFirebaseAuth();
13
13
  }
14
14
 
15
+ interface CentralAuthRedirectOptions {
16
+ centralAuthUrl: string;
17
+ stsEndpoint: string;
18
+ returnUrl: URL;
19
+ state: string;
20
+ accountId?: string;
21
+ projectId?: string;
22
+ }
23
+
24
+ /** Build a central-auth round trip without losing the app's requested account/project selection. */
25
+ export function centralAuthRedirectUrl({
26
+ centralAuthUrl,
27
+ stsEndpoint,
28
+ returnUrl,
29
+ state,
30
+ accountId,
31
+ projectId,
32
+ }: CentralAuthRedirectOptions): URL {
33
+ const selectedReturnUrl = new URL(returnUrl);
34
+ if (projectId) selectedReturnUrl.searchParams.set('p', projectId);
35
+ if (accountId) selectedReturnUrl.searchParams.set('a', accountId);
36
+
37
+ const url = new URL(centralAuthUrl);
38
+ url.searchParams.set('sts', stsEndpoint);
39
+ url.searchParams.set('redirect_uri', selectedReturnUrl.toString());
40
+ url.searchParams.set('state', state);
41
+ return url;
42
+ }
43
+
15
44
  /**
16
45
  * The page URL to return to after a central-auth round-trip (`redirect_uri`).
17
46
  *
@@ -139,7 +139,7 @@ export async function getFirebaseAuthToken(refresh?: boolean) {
139
139
  return user
140
140
  .getIdToken(refresh)
141
141
  .then((token) => {
142
- Env.logger.info('Got Firebase token', {
142
+ Env.logger.debug('Got Firebase token', {
143
143
  vertesia: {
144
144
  user_email: user.email,
145
145
  user_name: user.displayName,
@@ -23,7 +23,12 @@ export function useUXTracking() {
23
23
  console.debug('track event', eventName, eventProperties);
24
24
  }
25
25
 
26
- //GA via firebase
26
+ // GA via firebase — needs a complete Firebase config. A partial one (no apiKey, as in
27
+ // central-auth deployments and local setups) would make the Installations SDK log an
28
+ // async FirebaseError on every event, so analytics is a no-op there.
29
+ if (!Env.firebase?.apiKey) {
30
+ return;
31
+ }
27
32
  logEvent(getFirebaseAnalytics(), eventName, { ...eventProperties, debug_mode: !Env.isProd });
28
33
  };
29
34
 
@@ -3,6 +3,7 @@ import { TypeRegistryProvider, UserPermissionProvider } from '@vertesia/ui/featu
3
3
  import { LanguageBoundI18nProvider, LanguageProvider, type SupportedLanguage } from '@vertesia/ui/i18n';
4
4
  import { DevSessionProvider, UserSessionProvider } from '@vertesia/ui/session';
5
5
  import type { ReactNode } from 'react';
6
+ import { IframeAppContextSync } from './apps/IframeAppContextSync.js';
6
7
  import { SigninScreen } from './login/SigninScreen';
7
8
  import { SplashScreen } from './SplashScreen';
8
9
 
@@ -35,6 +36,7 @@ export function VertesiaShell({
35
36
  <ThemeProvider defaultTheme="system" storageKey="vite-ui-theme">
36
37
  <LanguageProvider defaultLanguage={defaultLanguage}>
37
38
  <LanguageBoundI18nProvider>
39
+ <IframeAppContextSync />
38
40
  {!authToken && (
39
41
  <>
40
42
  <SplashScreen icon={loadingIcon} />
@@ -0,0 +1,196 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { act, cleanup, render, screen, waitFor } from '@testing-library/react';
4
+ import { afterEach, describe, expect, it, vi } from 'vitest';
5
+ import { ThemeProvider, useTheme } from '../../core/index.js';
6
+ import { LanguageProvider, useLanguage } from '../../i18n/index.js';
7
+ import { IframeAppContextSync } from './IframeAppContextSync.js';
8
+ import {
9
+ IFRAME_APP_CONTEXT,
10
+ IFRAME_APP_CONTEXT_REQUEST,
11
+ IFRAME_APP_HOST_ORIGIN_PARAM,
12
+ IFRAME_APP_LOCATION_CHANGE,
13
+ IFRAME_APP_NAVIGATE,
14
+ } from './iframe-auth.js';
15
+
16
+ const originalParent = Object.getOwnPropertyDescriptor(window, 'parent');
17
+ const originalReferrer = Object.getOwnPropertyDescriptor(document, 'referrer');
18
+
19
+ afterEach(() => {
20
+ cleanup();
21
+ window.history.replaceState(null, '', '/');
22
+ localStorage.clear();
23
+ sessionStorage.clear();
24
+ document.documentElement.classList.remove('light', 'dark');
25
+ if (originalParent) Object.defineProperty(window, 'parent', originalParent);
26
+ else Reflect.deleteProperty(window, 'parent');
27
+ if (originalReferrer) Object.defineProperty(document, 'referrer', originalReferrer);
28
+ else Reflect.deleteProperty(document, 'referrer');
29
+ });
30
+
31
+ function ContextProbe() {
32
+ const { theme } = useTheme();
33
+ const { language } = useLanguage();
34
+ return <div>{`${theme}:${language}`}</div>;
35
+ }
36
+
37
+ describe('IframeAppContextSync', () => {
38
+ it('requests and applies host presentation state without overwriting standalone preferences', async () => {
39
+ const postMessage = vi.fn();
40
+ const parentWindow = { postMessage } as unknown as Window;
41
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
42
+ Object.defineProperty(document, 'referrer', {
43
+ configurable: true,
44
+ value: 'https://cloud.vertesia.io/app/sample',
45
+ });
46
+ localStorage.setItem('custom-theme', 'dark');
47
+ localStorage.setItem('custom-language', 'en');
48
+
49
+ render(
50
+ <ThemeProvider storageKey="custom-theme">
51
+ <LanguageProvider storageKey="custom-language">
52
+ <IframeAppContextSync />
53
+ <ContextProbe />
54
+ </LanguageProvider>
55
+ </ThemeProvider>,
56
+ );
57
+
58
+ expect(parentWindow.postMessage).toHaveBeenCalledWith(
59
+ { type: IFRAME_APP_CONTEXT_REQUEST },
60
+ 'https://cloud.vertesia.io',
61
+ );
62
+
63
+ window.dispatchEvent(
64
+ new MessageEvent('message', {
65
+ data: { type: IFRAME_APP_CONTEXT, theme: 'light', language: 'fr' },
66
+ origin: 'https://attacker.example.com',
67
+ source: parentWindow,
68
+ }),
69
+ );
70
+ expect(screen.getByText('dark:en')).toBeTruthy();
71
+
72
+ act(() => {
73
+ window.dispatchEvent(
74
+ new MessageEvent('message', {
75
+ data: { type: IFRAME_APP_CONTEXT, theme: 'light', language: 'fr' },
76
+ origin: 'https://cloud.vertesia.io',
77
+ source: parentWindow,
78
+ }),
79
+ );
80
+ });
81
+
82
+ await waitFor(() => expect(screen.getByText('light:fr')).toBeTruthy());
83
+ expect(localStorage.getItem('custom-theme')).toBe('dark');
84
+ expect(localStorage.getItem('custom-language')).toBe('en');
85
+ expect(postMessage.mock.calls.filter(([message]) => message.type === IFRAME_APP_CONTEXT_REQUEST)).toHaveLength(
86
+ 1,
87
+ );
88
+ });
89
+
90
+ it('applies same-origin host navigation without reloading the document', () => {
91
+ const parentWindow = { postMessage: vi.fn() } as unknown as Window;
92
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
93
+ Object.defineProperty(document, 'referrer', {
94
+ configurable: true,
95
+ value: 'https://cloud.vertesia.io/app/sample',
96
+ });
97
+ localStorage.setItem('vite-ui-theme', 'dark');
98
+ localStorage.setItem('vertesia-ui-language', 'en');
99
+ window.history.replaceState(null, '', '/app/');
100
+ const popstate = vi.fn();
101
+ window.addEventListener('popstate', popstate);
102
+
103
+ render(
104
+ <ThemeProvider>
105
+ <LanguageProvider>
106
+ <IframeAppContextSync />
107
+ </LanguageProvider>
108
+ </ThemeProvider>,
109
+ );
110
+
111
+ window.dispatchEvent(
112
+ new MessageEvent('message', {
113
+ data: { type: IFRAME_APP_NAVIGATE, url: 'https://attacker.example.com/stolen' },
114
+ origin: 'https://cloud.vertesia.io',
115
+ source: parentWindow,
116
+ }),
117
+ );
118
+ expect(window.location.pathname).toBe('/app/');
119
+
120
+ const target = `${window.location.origin}/app/reports?__vertesia_slot=content`;
121
+ window.dispatchEvent(
122
+ new MessageEvent('message', {
123
+ data: { type: IFRAME_APP_NAVIGATE, url: target },
124
+ origin: 'https://cloud.vertesia.io',
125
+ source: parentWindow,
126
+ }),
127
+ );
128
+
129
+ expect(window.location.pathname).toBe('/app/reports');
130
+ expect(window.location.search).toBe('?__vertesia_slot=content');
131
+ expect(popstate).toHaveBeenCalledTimes(1);
132
+ window.removeEventListener('popstate', popstate);
133
+ });
134
+
135
+ it('acknowledges host navigation when the iframe is already at the requested URL', () => {
136
+ const parentWindow = { postMessage: vi.fn() } as unknown as Window;
137
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
138
+ localStorage.setItem('vite-ui-theme', 'dark');
139
+ window.history.replaceState(
140
+ null,
141
+ '',
142
+ `/app/reports?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fcloud.vertesia.io`,
143
+ );
144
+
145
+ render(
146
+ <ThemeProvider>
147
+ <LanguageProvider>
148
+ <IframeAppContextSync />
149
+ </LanguageProvider>
150
+ </ThemeProvider>,
151
+ );
152
+ parentWindow.postMessage = vi.fn();
153
+
154
+ window.dispatchEvent(
155
+ new MessageEvent('message', {
156
+ data: { type: IFRAME_APP_NAVIGATE, url: window.location.href },
157
+ origin: 'https://cloud.vertesia.io',
158
+ source: parentWindow,
159
+ }),
160
+ );
161
+
162
+ expect(parentWindow.postMessage).toHaveBeenCalledWith(
163
+ { type: IFRAME_APP_LOCATION_CHANGE, url: window.location.href },
164
+ 'https://cloud.vertesia.io',
165
+ );
166
+ });
167
+
168
+ it('reports app-initiated history navigation to the embedding Studio', () => {
169
+ const parentWindow = { postMessage: vi.fn() } as unknown as Window;
170
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
171
+ window.history.replaceState(null, '', `/app/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fcloud.vertesia.io`);
172
+ localStorage.setItem('vite-ui-theme', 'dark');
173
+ localStorage.setItem('vertesia-ui-language', 'en');
174
+
175
+ render(
176
+ <ThemeProvider>
177
+ <LanguageProvider>
178
+ <IframeAppContextSync />
179
+ </LanguageProvider>
180
+ </ThemeProvider>,
181
+ );
182
+ parentWindow.postMessage = vi.fn();
183
+
184
+ window.history.pushState(null, '', '/app/reports?period=week');
185
+
186
+ expect(parentWindow.postMessage).toHaveBeenCalledWith(
187
+ {
188
+ type: IFRAME_APP_LOCATION_CHANGE,
189
+ url:
190
+ `${window.location.origin}/app/reports?period=week&` +
191
+ `${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fcloud.vertesia.io`,
192
+ },
193
+ 'https://cloud.vertesia.io',
194
+ );
195
+ });
196
+ });
@@ -0,0 +1,101 @@
1
+ import { useEffect } from 'react';
2
+ import { useTheme } from '../../core/components/shadcn/theme/ThemeProvider.js';
3
+ import { useLanguage } from '../../i18n/LanguageProvider.js';
4
+ import {
5
+ IFRAME_APP_CONTEXT_REQUEST,
6
+ IFRAME_APP_HOST_ORIGIN_PARAM,
7
+ IFRAME_APP_LOCATION_CHANGE,
8
+ type IframeAppContextRequest,
9
+ type IframeAppLocationChange,
10
+ isIframeAppContext,
11
+ isIframeAppNavigate,
12
+ resolveIframeHostOrigin,
13
+ } from './iframe-auth.js';
14
+
15
+ function preserveIframeHostOrigin(url: string | URL | null | undefined): string | URL | null | undefined {
16
+ if (url === null || url === undefined) return url;
17
+ const hostOrigin = new URL(window.location.href).searchParams.get(IFRAME_APP_HOST_ORIGIN_PARAM);
18
+ if (!hostOrigin) return url;
19
+
20
+ try {
21
+ const target = new URL(url, window.location.href);
22
+ if (target.origin !== window.location.origin) return url;
23
+ target.searchParams.set(IFRAME_APP_HOST_ORIGIN_PARAM, hostOrigin);
24
+ return target;
25
+ } catch {
26
+ return url;
27
+ }
28
+ }
29
+
30
+ /** Applies context and navigation supplied by an embedding Studio without changing standalone preferences. */
31
+ export function IframeAppContextSync() {
32
+ const { setTheme } = useTheme();
33
+ const { setLanguage } = useLanguage();
34
+
35
+ useEffect(() => {
36
+ const parentOrigin = resolveIframeHostOrigin();
37
+ if (!parentOrigin) return;
38
+
39
+ const reportLocation = () => {
40
+ const message = {
41
+ type: IFRAME_APP_LOCATION_CHANGE,
42
+ url: window.location.href,
43
+ } satisfies IframeAppLocationChange;
44
+ window.parent.postMessage(message, parentOrigin);
45
+ };
46
+
47
+ const originalPushState = window.history.pushState;
48
+ const originalReplaceState = window.history.replaceState;
49
+ const pushState: History['pushState'] = (data, unused, url) => {
50
+ originalPushState.call(window.history, data, unused, preserveIframeHostOrigin(url));
51
+ reportLocation();
52
+ };
53
+ const replaceState: History['replaceState'] = (data, unused, url) => {
54
+ originalReplaceState.call(window.history, data, unused, preserveIframeHostOrigin(url));
55
+ reportLocation();
56
+ };
57
+ window.history.pushState = pushState;
58
+ window.history.replaceState = replaceState;
59
+
60
+ const onMessage = (event: MessageEvent<unknown>) => {
61
+ if (event.source !== window.parent || event.origin !== parentOrigin) return;
62
+ if (isIframeAppContext(event.data)) {
63
+ const context = event.data;
64
+ setTheme(context.theme, { persist: false });
65
+ setLanguage(context.language, { persist: false });
66
+ return;
67
+ }
68
+ if (isIframeAppNavigate(event.data)) {
69
+ let target: URL;
70
+ try {
71
+ target = new URL(event.data.url, window.location.href);
72
+ } catch {
73
+ return;
74
+ }
75
+ if (target.origin !== window.location.origin) return;
76
+ if (target.href === window.location.href) {
77
+ // Acknowledge no-op navigation so the host does not wait forever and suppress later app routing.
78
+ reportLocation();
79
+ return;
80
+ }
81
+ window.history.replaceState(window.history.state, '', target);
82
+ window.dispatchEvent(new PopStateEvent('popstate', { state: window.history.state }));
83
+ }
84
+ };
85
+ const request = { type: IFRAME_APP_CONTEXT_REQUEST } satisfies IframeAppContextRequest;
86
+ window.addEventListener('message', onMessage);
87
+ window.addEventListener('popstate', reportLocation);
88
+ window.addEventListener('hashchange', reportLocation);
89
+ window.parent.postMessage(request, parentOrigin);
90
+ reportLocation();
91
+ return () => {
92
+ window.removeEventListener('message', onMessage);
93
+ window.removeEventListener('popstate', reportLocation);
94
+ window.removeEventListener('hashchange', reportLocation);
95
+ if (window.history.pushState === pushState) window.history.pushState = originalPushState;
96
+ if (window.history.replaceState === replaceState) window.history.replaceState = originalReplaceState;
97
+ };
98
+ }, [setLanguage, setTheme]);
99
+
100
+ return null;
101
+ }
@@ -0,0 +1,118 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { afterEach, describe, expect, it } from 'vitest';
4
+ import {
5
+ IFRAME_APP_HOST_ORIGIN_PARAM,
6
+ IFRAME_AUTH_REQUEST,
7
+ IFRAME_AUTH_RESPONSE,
8
+ requestIframeHostAuthToken,
9
+ resolveIframeHostOrigin,
10
+ } from './iframe-auth.js';
11
+
12
+ const originalParent = Object.getOwnPropertyDescriptor(window, 'parent');
13
+ const originalReferrer = Object.getOwnPropertyDescriptor(document, 'referrer');
14
+
15
+ afterEach(() => {
16
+ window.history.replaceState(null, '', '/');
17
+ window.sessionStorage.clear();
18
+ if (originalParent) Object.defineProperty(window, 'parent', originalParent);
19
+ else Reflect.deleteProperty(window, 'parent');
20
+ if (originalReferrer) Object.defineProperty(document, 'referrer', originalReferrer);
21
+ else Reflect.deleteProperty(document, 'referrer');
22
+ });
23
+
24
+ describe('iframe host authentication', () => {
25
+ it('resolves an explicit trusted host origin', () => {
26
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
27
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
28
+ window.history.replaceState(null, '', `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fcloud.vertesia.io`);
29
+
30
+ expect(resolveIframeHostOrigin()).toBe('https://cloud.vertesia.io');
31
+ });
32
+
33
+ it('accepts a branch Studio UI origin', () => {
34
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
35
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
36
+ window.history.replaceState(
37
+ null,
38
+ '',
39
+ `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fdev-feat-iframe.ui.dev1.vertesia.io`,
40
+ );
41
+
42
+ expect(resolveIframeHostOrigin()).toBe('https://dev-feat-iframe.ui.dev1.vertesia.io');
43
+ });
44
+
45
+ it('rejects untrusted query and referrer origins', () => {
46
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
47
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
48
+ window.history.replaceState(null, '', `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fevil.example.com`);
49
+ Object.defineProperty(document, 'referrer', {
50
+ configurable: true,
51
+ value: 'https://referrer.example.com/embed',
52
+ });
53
+
54
+ expect(resolveIframeHostOrigin()).toBeUndefined();
55
+ });
56
+
57
+ it('rejects a shared Vertesia app-gateway origin', () => {
58
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
59
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
60
+ window.history.replaceState(null, '', `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fapps.dev1.vertesia.io`);
61
+
62
+ expect(resolveIframeHostOrigin()).toBeUndefined();
63
+ });
64
+
65
+ it('rejects an origin containing embedded credentials', () => {
66
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
67
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
68
+ window.history.replaceState(
69
+ null,
70
+ '',
71
+ `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fuser%3Asecret%40cloud.vertesia.io`,
72
+ );
73
+
74
+ expect(resolveIframeHostOrigin()).toBeUndefined();
75
+ });
76
+
77
+ it('accepts a loopback host for a loopback child app', () => {
78
+ const parentWindow = { postMessage: () => undefined } as unknown as Window;
79
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
80
+ window.history.replaceState(null, '', `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=http%3A%2F%2Flocalhost%3A5173`);
81
+
82
+ expect(resolveIframeHostOrigin()).toBe('http://localhost:5173');
83
+ });
84
+
85
+ it('ignores an empty early response and waits for a usable host token', async () => {
86
+ const requests: unknown[] = [];
87
+ const parentWindow = { postMessage: (message: unknown) => requests.push(message) } as unknown as Window;
88
+ Object.defineProperty(window, 'parent', { configurable: true, value: parentWindow });
89
+ window.history.replaceState(null, '', `/?${IFRAME_APP_HOST_ORIGIN_PARAM}=https%3A%2F%2Fcloud.vertesia.io`);
90
+
91
+ let settled = false;
92
+ const tokenPromise = requestIframeHostAuthToken().then((token) => {
93
+ settled = true;
94
+ return token;
95
+ });
96
+ const request = requests[0] as { type: string; requestId: string };
97
+ expect(request.type).toBe(IFRAME_AUTH_REQUEST);
98
+
99
+ window.dispatchEvent(
100
+ new MessageEvent('message', {
101
+ data: { type: IFRAME_AUTH_RESPONSE, requestId: request.requestId },
102
+ origin: 'https://cloud.vertesia.io',
103
+ source: parentWindow,
104
+ }),
105
+ );
106
+ await Promise.resolve();
107
+ expect(settled).toBe(false);
108
+
109
+ window.dispatchEvent(
110
+ new MessageEvent('message', {
111
+ data: { type: IFRAME_AUTH_RESPONSE, requestId: request.requestId, token: 'fresh-token' },
112
+ origin: 'https://cloud.vertesia.io',
113
+ source: parentWindow,
114
+ }),
115
+ );
116
+ await expect(tokenPromise).resolves.toBe('fresh-token');
117
+ });
118
+ });