@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.
Files changed (508) hide show
  1. package/lib/core/components/Avatar.d.ts.map +1 -1
  2. package/lib/core/components/Avatar.js +3 -3
  3. package/lib/core/components/Avatar.js.map +1 -1
  4. package/lib/core/components/ComboBox.js +1 -1
  5. package/lib/core/components/ComboBox.js.map +1 -1
  6. package/lib/core/components/FileUpload.js +1 -1
  7. package/lib/core/components/FileUpload.js.map +1 -1
  8. package/lib/core/components/Link.js +1 -1
  9. package/lib/core/components/Link.js.map +1 -1
  10. package/lib/core/components/SelectList.js +1 -1
  11. package/lib/core/components/SelectList.js.map +1 -1
  12. package/lib/core/components/SidePanel.js +1 -1
  13. package/lib/core/components/SidePanel.js.map +1 -1
  14. package/lib/core/components/Spinner.js +1 -1
  15. package/lib/core/components/Spinner.js.map +1 -1
  16. package/lib/core/components/TagsInput.js +8 -8
  17. package/lib/core/components/TagsInput.js.map +1 -1
  18. package/lib/core/components/shadcn/MessageBox.js +1 -1
  19. package/lib/core/components/shadcn/MessageBox.js.map +1 -1
  20. package/lib/core/components/shadcn/button.js +1 -1
  21. package/lib/core/components/shadcn/button.js.map +1 -1
  22. package/lib/core/components/shadcn/card.d.ts.map +1 -1
  23. package/lib/core/components/shadcn/card.js +1 -1
  24. package/lib/core/components/shadcn/card.js.map +1 -1
  25. package/lib/core/components/shadcn/command.js +5 -5
  26. package/lib/core/components/shadcn/command.js.map +1 -1
  27. package/lib/core/components/shadcn/filters/DynamicLabel.js +1 -1
  28. package/lib/core/components/shadcn/filters/DynamicLabel.js.map +1 -1
  29. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +3 -3
  30. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -1
  31. package/lib/core/components/shadcn/input.js +3 -3
  32. package/lib/core/components/shadcn/input.js.map +1 -1
  33. package/lib/core/components/shadcn/modal/ConfirmModal.js +1 -1
  34. package/lib/core/components/shadcn/modal/ConfirmModal.js.map +1 -1
  35. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  36. package/lib/core/components/shadcn/modal/dialog.js +2 -2
  37. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  38. package/lib/core/components/shadcn/overflowTabs.js +2 -2
  39. package/lib/core/components/shadcn/overflowTabs.js.map +1 -1
  40. package/lib/core/components/shadcn/popover.js +1 -1
  41. package/lib/core/components/shadcn/popover.js.map +1 -1
  42. package/lib/core/components/shadcn/radioGroup.d.ts.map +1 -1
  43. package/lib/core/components/shadcn/radioGroup.js +3 -3
  44. package/lib/core/components/shadcn/radioGroup.js.map +1 -1
  45. package/lib/core/components/shadcn/selectBox.js +1 -1
  46. package/lib/core/components/shadcn/selectBox.js.map +1 -1
  47. package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
  48. package/lib/core/components/shadcn/tabs.js +5 -2
  49. package/lib/core/components/shadcn/tabs.js.map +1 -1
  50. package/lib/core/components/styles.js +1 -1
  51. package/lib/core/components/styles.js.map +1 -1
  52. package/lib/core/components/table/index.js +1 -1
  53. package/lib/core/hooks/useFetch.d.ts.map +1 -1
  54. package/lib/core/hooks/useFetch.js +2 -0
  55. package/lib/core/hooks/useFetch.js.map +1 -1
  56. package/lib/features/activity-doc/ActivityDoc.js +8 -8
  57. package/lib/features/activity-doc/ActivityDoc.js.map +1 -1
  58. package/lib/features/agent/chat/AgentChart.js +1 -1
  59. package/lib/features/agent/chat/AgentChart.js.map +1 -1
  60. package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
  61. package/lib/features/agent/chat/AskUserWidget.js +13 -13
  62. package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
  63. package/lib/features/agent/chat/JumpingDots.js +1 -1
  64. package/lib/features/agent/chat/JumpingDots.js.map +1 -1
  65. package/lib/features/agent/chat/ModernAgentConversation.js +1 -1
  66. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  67. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  68. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +22 -9
  69. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  70. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +5 -5
  71. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
  72. package/lib/features/agent/chat/ModernAgentOutput/Header.js +1 -1
  73. package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  74. package/lib/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.js +1 -1
  75. package/lib/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.js.map +1 -1
  76. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +1 -1
  77. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
  78. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  79. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +7 -7
  80. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  81. package/lib/features/agent/chat/ModernAgentOutput/MessagesContainer.js +1 -1
  82. package/lib/features/agent/chat/ModernAgentOutput/MessagesContainer.js.map +1 -1
  83. package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
  84. package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.js +10 -10
  85. package/lib/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
  86. package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js +1 -1
  87. package/lib/features/agent/chat/ModernAgentOutput/SlideInPanel.js.map +1 -1
  88. package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.d.ts.map +1 -1
  89. package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js +1 -1
  90. package/lib/features/agent/chat/ModernAgentOutput/SlidingMessages.js.map +1 -1
  91. package/lib/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +17 -17
  92. package/lib/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
  93. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js +1 -1
  94. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
  95. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
  96. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +14 -2
  97. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
  98. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
  99. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +15 -15
  100. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  101. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
  102. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +18 -0
  103. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
  104. package/lib/features/agent/chat/SlidingThinkingIndicator.d.ts.map +1 -1
  105. package/lib/features/agent/chat/SlidingThinkingIndicator.js +5 -2
  106. package/lib/features/agent/chat/SlidingThinkingIndicator.js.map +1 -1
  107. package/lib/features/agent/chat/VegaLiteChart.d.ts.map +1 -1
  108. package/lib/features/agent/chat/VegaLiteChart.js +6 -2
  109. package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
  110. package/lib/features/errors/RowErrorBoundary.js +1 -1
  111. package/lib/features/errors/RowErrorBoundary.js.map +1 -1
  112. package/lib/features/facets/AgentRunnerFacetsNav.js +1 -1
  113. package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
  114. package/lib/features/facets/utils/VInteractionFacet.d.ts +3 -5
  115. package/lib/features/facets/utils/VInteractionFacet.d.ts.map +1 -1
  116. package/lib/features/facets/utils/VInteractionFacet.js +10 -23
  117. package/lib/features/facets/utils/VInteractionFacet.js.map +1 -1
  118. package/lib/features/facets/utils/VUserFacet.js +1 -1
  119. package/lib/features/facets/utils/VUserFacet.js.map +1 -1
  120. package/lib/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  121. package/lib/features/layout/GenericPageNavHeader.js +4 -1
  122. package/lib/features/layout/GenericPageNavHeader.js.map +1 -1
  123. package/lib/features/layout/NotFoundView.js +1 -1
  124. package/lib/features/layout/NotFoundView.js.map +1 -1
  125. package/lib/features/magic-pdf/AnnotatedImageSlider.js +4 -12
  126. package/lib/features/magic-pdf/AnnotatedImageSlider.js.map +1 -1
  127. package/lib/features/magic-pdf/ExtractedContentView.js +4 -4
  128. package/lib/features/magic-pdf/ExtractedContentView.js.map +1 -1
  129. package/lib/features/magic-pdf/MagicPdfView.js +1 -1
  130. package/lib/features/magic-pdf/MagicPdfView.js.map +1 -1
  131. package/lib/features/pdf-viewer/PdfPageRenderer.js +2 -2
  132. package/lib/features/pdf-viewer/PdfPageRenderer.js.map +1 -1
  133. package/lib/features/pdf-viewer/PdfPageSlider.js +3 -3
  134. package/lib/features/pdf-viewer/PdfPageSlider.js.map +1 -1
  135. package/lib/features/pdf-viewer/SimplePdfViewer.js +1 -1
  136. package/lib/features/pdf-viewer/SimplePdfViewer.js.map +1 -1
  137. package/lib/features/permissions/UserPermissionsProvider.d.ts +2 -1
  138. package/lib/features/permissions/UserPermissionsProvider.d.ts.map +1 -1
  139. package/lib/features/permissions/UserPermissionsProvider.js +35 -22
  140. package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
  141. package/lib/features/permissions/useRoleMappings.d.ts +19 -0
  142. package/lib/features/permissions/useRoleMappings.d.ts.map +1 -0
  143. package/lib/features/permissions/useRoleMappings.js +87 -0
  144. package/lib/features/permissions/useRoleMappings.js.map +1 -0
  145. package/lib/features/store/collections/SelectCollection.js +1 -1
  146. package/lib/features/store/collections/SelectCollection.js.map +1 -1
  147. package/lib/features/store/objects/DocumentPreviewPanel.d.ts.map +1 -1
  148. package/lib/features/store/objects/DocumentPreviewPanel.js +9 -9
  149. package/lib/features/store/objects/DocumentPreviewPanel.js.map +1 -1
  150. package/lib/features/store/objects/DocumentTable.js +1 -1
  151. package/lib/features/store/objects/DocumentTable.js.map +1 -1
  152. package/lib/features/store/objects/components/DocumentIcon.js +2 -2
  153. package/lib/features/store/objects/components/DocumentIcon.js.map +1 -1
  154. package/lib/features/store/objects/components/DocumentInput.js +1 -1
  155. package/lib/features/store/objects/components/DocumentInput.js.map +1 -1
  156. package/lib/features/store/objects/components/PropertiesEditorModal.js +1 -1
  157. package/lib/features/store/objects/components/PropertiesEditorModal.js.map +1 -1
  158. package/lib/features/store/objects/components/SaveVersionConfirmModal.js +1 -1
  159. package/lib/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
  160. package/lib/features/store/objects/layout/documentLayout.d.ts.map +1 -1
  161. package/lib/features/store/objects/layout/documentLayout.js +2 -2
  162. package/lib/features/store/objects/layout/documentLayout.js.map +1 -1
  163. package/lib/features/store/objects/selection/SelectionActions.js +1 -1
  164. package/lib/features/store/objects/selection/SelectionActions.js.map +1 -1
  165. package/lib/features/store/types/IntakePolicyEditor.d.ts +10 -1
  166. package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
  167. package/lib/features/store/types/IntakePolicyEditor.js +29 -19
  168. package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
  169. package/lib/features/store/types/IntakePolicyForm.d.ts +1 -1
  170. package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
  171. package/lib/features/store/types/IntakePolicyForm.js +5 -3
  172. package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
  173. package/lib/features/store/types/SelectContentTypeModal.js +1 -1
  174. package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
  175. package/lib/features/user/UserAvatar.js +2 -2
  176. package/lib/features/user/UserAvatar.js.map +1 -1
  177. package/lib/features/user/UserInfo.d.ts.map +1 -1
  178. package/lib/features/user/UserInfo.js +7 -7
  179. package/lib/features/user/UserInfo.js.map +1 -1
  180. package/lib/features/utils/index.d.ts +1 -0
  181. package/lib/features/utils/index.d.ts.map +1 -1
  182. package/lib/features/utils/index.js +1 -0
  183. package/lib/features/utils/index.js.map +1 -1
  184. package/lib/features/utils/interaction.d.ts +55 -0
  185. package/lib/features/utils/interaction.d.ts.map +1 -0
  186. package/lib/features/utils/interaction.js +77 -0
  187. package/lib/features/utils/interaction.js.map +1 -0
  188. package/lib/features/views/ViewResults.js +2 -2
  189. package/lib/features/views/ViewResults.js.map +1 -1
  190. package/lib/i18n/locales/ar.json +7 -1
  191. package/lib/i18n/locales/de.json +7 -1
  192. package/lib/i18n/locales/en.json +7 -1
  193. package/lib/i18n/locales/es.json +7 -1
  194. package/lib/i18n/locales/fr.json +7 -1
  195. package/lib/i18n/locales/it.json +7 -1
  196. package/lib/i18n/locales/ja.json +7 -1
  197. package/lib/i18n/locales/ko.json +7 -1
  198. package/lib/i18n/locales/pt.json +7 -1
  199. package/lib/i18n/locales/ru.json +7 -1
  200. package/lib/i18n/locales/tr.json +7 -1
  201. package/lib/i18n/locales/zh-TW.json +7 -1
  202. package/lib/i18n/locales/zh.json +7 -1
  203. package/lib/layout/FullHeightLayout.js +2 -2
  204. package/lib/layout/FullHeightLayout.js.map +1 -1
  205. package/lib/layout/Navbar.js +4 -4
  206. package/lib/layout/Navbar.js.map +1 -1
  207. package/lib/layout/Sidebar.js +1 -1
  208. package/lib/layout/Sidebar.js.map +1 -1
  209. package/lib/session/UserSessionProvider.d.ts.map +1 -1
  210. package/lib/session/UserSessionProvider.js +2 -13
  211. package/lib/session/UserSessionProvider.js.map +1 -1
  212. package/lib/session/auth/authState.d.ts +13 -0
  213. package/lib/session/auth/authState.d.ts.map +1 -0
  214. package/lib/session/auth/authState.js +37 -0
  215. package/lib/session/auth/authState.js.map +1 -0
  216. package/lib/session/auth/domainRouting.d.ts +39 -0
  217. package/lib/session/auth/domainRouting.d.ts.map +1 -1
  218. package/lib/session/auth/domainRouting.js +85 -0
  219. package/lib/session/auth/domainRouting.js.map +1 -1
  220. package/lib/session/auth/useAuthState.d.ts +4 -7
  221. package/lib/session/auth/useAuthState.d.ts.map +1 -1
  222. package/lib/session/auth/useAuthState.js +5 -41
  223. package/lib/session/auth/useAuthState.js.map +1 -1
  224. package/lib/session/index.d.ts +1 -0
  225. package/lib/session/index.d.ts.map +1 -1
  226. package/lib/session/index.js +2 -0
  227. package/lib/session/index.js.map +1 -1
  228. package/lib/shell/SplashScreen.d.ts +1 -1
  229. package/lib/shell/SplashScreen.d.ts.map +1 -1
  230. package/lib/shell/SplashScreen.js +6 -2
  231. package/lib/shell/SplashScreen.js.map +1 -1
  232. package/lib/shell/VertesiaShell.js +1 -1
  233. package/lib/shell/VertesiaShell.js.map +1 -1
  234. package/lib/shell/apps/AppProjectSelector.js +1 -1
  235. package/lib/shell/apps/AppProjectSelector.js.map +1 -1
  236. package/lib/shell/apps/StandaloneApp.js +2 -2
  237. package/lib/shell/apps/StandaloneApp.js.map +1 -1
  238. package/lib/shell/login/SignInPrimitives.js +2 -2
  239. package/lib/shell/login/SignInPrimitives.js.map +1 -1
  240. package/lib/shell/login/SigninScreen.js +1 -1
  241. package/lib/shell/login/SigninScreen.js.map +1 -1
  242. package/lib/shell/login/SignupForm.js +1 -1
  243. package/lib/shell/login/SignupForm.js.map +1 -1
  244. package/lib/shell/login/TerminalLogin.js +2 -2
  245. package/lib/shell/login/TerminalLogin.js.map +1 -1
  246. package/lib/shell/login/UserInfo.d.ts.map +1 -1
  247. package/lib/shell/login/UserInfo.js +1 -1
  248. package/lib/shell/login/UserInfo.js.map +1 -1
  249. package/lib/shell/login/UserSessionMenu.js +1 -1
  250. package/lib/shell/login/UserSessionMenu.js.map +1 -1
  251. package/lib/vertesia-ui-core.js +7 -7
  252. package/lib/vertesia-ui-core.js.map +1 -1
  253. package/lib/vertesia-ui-features.js +179 -182
  254. package/lib/vertesia-ui-features.js.map +1 -1
  255. package/lib/vertesia-ui-i18n.BfN7iOHb.chunk.js +5 -0
  256. package/lib/vertesia-ui-i18n.BfN7iOHb.chunk.js.map +1 -0
  257. package/lib/vertesia-ui-i18n.BjH2zEZw.chunk.js +5 -0
  258. package/lib/vertesia-ui-i18n.BjH2zEZw.chunk.js.map +1 -0
  259. package/lib/vertesia-ui-i18n.BjSwAZXl.chunk.js +5 -0
  260. package/lib/vertesia-ui-i18n.BjSwAZXl.chunk.js.map +1 -0
  261. package/lib/vertesia-ui-i18n.C7PUm5Au.chunk.js +5 -0
  262. package/lib/vertesia-ui-i18n.C7PUm5Au.chunk.js.map +1 -0
  263. package/lib/vertesia-ui-i18n.CF_1mUS5.chunk.js +5 -0
  264. package/lib/vertesia-ui-i18n.CF_1mUS5.chunk.js.map +1 -0
  265. package/lib/vertesia-ui-i18n.ChfUl3_-.chunk.js +5 -0
  266. package/lib/vertesia-ui-i18n.ChfUl3_-.chunk.js.map +1 -0
  267. package/lib/vertesia-ui-i18n.D-Sk-5d1.chunk.js +5 -0
  268. package/lib/vertesia-ui-i18n.D-Sk-5d1.chunk.js.map +1 -0
  269. package/lib/vertesia-ui-i18n.D4rnu1_S.chunk.js +5 -0
  270. package/lib/vertesia-ui-i18n.D4rnu1_S.chunk.js.map +1 -0
  271. package/lib/vertesia-ui-i18n.DDf0-laK.chunk.js +5 -0
  272. package/lib/vertesia-ui-i18n.DDf0-laK.chunk.js.map +1 -0
  273. package/lib/vertesia-ui-i18n.DN79y06J.chunk.js +5 -0
  274. package/lib/vertesia-ui-i18n.DN79y06J.chunk.js.map +1 -0
  275. package/lib/vertesia-ui-i18n.DWLIciYQ.chunk.js +5 -0
  276. package/lib/vertesia-ui-i18n.DWLIciYQ.chunk.js.map +1 -0
  277. package/lib/vertesia-ui-i18n.DvF_YaAJ.chunk.js +5 -0
  278. package/lib/vertesia-ui-i18n.DvF_YaAJ.chunk.js.map +1 -0
  279. package/lib/vertesia-ui-i18n.js +2 -2
  280. package/lib/vertesia-ui-layout.js +1 -1
  281. package/lib/vertesia-ui-layout.js.map +1 -1
  282. package/lib/vertesia-ui-rich-text.js +24 -24
  283. package/lib/vertesia-ui-rich-text.js.map +1 -1
  284. package/lib/vertesia-ui-session.js +1 -1
  285. package/lib/vertesia-ui-session.js.map +1 -1
  286. package/lib/vertesia-ui-shell.js +3 -3
  287. package/lib/vertesia-ui-shell.js.map +1 -1
  288. package/lib/vertesia-ui-widgets.js +54 -54
  289. package/lib/vertesia-ui-widgets.js.map +1 -1
  290. package/lib/widgets/Progress.js +1 -1
  291. package/lib/widgets/Progress.js.map +1 -1
  292. package/lib/widgets/form/Form.js +2 -2
  293. package/lib/widgets/form/Form.js.map +1 -1
  294. package/lib/widgets/form/fields.js +2 -2
  295. package/lib/widgets/form/fields.js.map +1 -1
  296. package/lib/widgets/json-view/JSONView.js +1 -1
  297. package/lib/widgets/json-view/JSONView.js.map +1 -1
  298. package/lib/widgets/markdown/MermaidDiagram.js +1 -1
  299. package/lib/widgets/markdown/MermaidDiagram.js.map +1 -1
  300. package/lib/widgets/markdown/remarkDirectiveHandler.d.ts +7 -2
  301. package/lib/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -1
  302. package/lib/widgets/markdown/remarkDirectiveHandler.js +19 -4
  303. package/lib/widgets/markdown/remarkDirectiveHandler.js.map +1 -1
  304. package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  305. package/lib/widgets/monacoEditor/MonacoEditor.js +4 -2
  306. package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  307. package/lib/widgets/monacoEditor/index.d.ts +1 -0
  308. package/lib/widgets/monacoEditor/index.d.ts.map +1 -1
  309. package/lib/widgets/monacoEditor/index.js +1 -0
  310. package/lib/widgets/monacoEditor/index.js.map +1 -1
  311. package/lib/widgets/monacoEditor/loadMonaco.d.ts +45 -0
  312. package/lib/widgets/monacoEditor/loadMonaco.d.ts.map +1 -0
  313. package/lib/widgets/monacoEditor/loadMonaco.js +62 -0
  314. package/lib/widgets/monacoEditor/loadMonaco.js.map +1 -0
  315. package/lib/widgets/properties/PropertiesView.js +1 -1
  316. package/lib/widgets/properties/PropertiesView.js.map +1 -1
  317. package/lib/widgets/schema-editor/editor/Editable.js +2 -2
  318. package/lib/widgets/schema-editor/editor/Editable.js.map +1 -1
  319. package/lib/widgets/schema-editor/editor/PropertyEditor.js +1 -1
  320. package/lib/widgets/schema-editor/editor/PropertyEditor.js.map +1 -1
  321. package/lib/widgets/schema-editor/editor/SchemaEditor.js +2 -2
  322. package/lib/widgets/schema-editor/editor/SchemaEditor.js.map +1 -1
  323. package/lib/widgets/upload/DropZone.js +1 -1
  324. package/lib/widgets/upload/DropZone.js.map +1 -1
  325. package/lib/widgets/upload/UploadResultCategory.d.ts +1 -1
  326. package/lib/widgets/upload/UploadResultCategory.d.ts.map +1 -1
  327. package/lib/widgets/upload/UploadResultCategory.js +3 -3
  328. package/lib/widgets/upload/UploadResultCategory.js.map +1 -1
  329. package/lib/widgets/upload/UploadSummary.js +1 -1
  330. package/lib/widgets/upload/UploadSummary.js.map +1 -1
  331. package/lib/widgets/xml-viewer/components/XMLViewer.d.ts.map +1 -1
  332. package/lib/widgets/xml-viewer/components/XMLViewer.js +7 -3
  333. package/lib/widgets/xml-viewer/components/XMLViewer.js.map +1 -1
  334. package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
  335. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +11 -13
  336. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
  337. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +41 -14
  338. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
  339. package/package.json +7 -7
  340. package/src/__tests__/contrast.test.ts +1 -0
  341. package/src/core/components/Avatar.tsx +3 -3
  342. package/src/core/components/ComboBox.tsx +1 -1
  343. package/src/core/components/FileUpload.tsx +4 -4
  344. package/src/core/components/Link.tsx +1 -1
  345. package/src/core/components/SelectList.tsx +1 -1
  346. package/src/core/components/SidePanel.tsx +1 -1
  347. package/src/core/components/Spinner.tsx +1 -1
  348. package/src/core/components/TagsInput.tsx +8 -8
  349. package/src/core/components/shadcn/MessageBox.tsx +1 -1
  350. package/src/core/components/shadcn/button.tsx +1 -1
  351. package/src/core/components/shadcn/card.tsx +1 -3
  352. package/src/core/components/shadcn/command.tsx +5 -5
  353. package/src/core/components/shadcn/filters/DynamicLabel.tsx +1 -1
  354. package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +3 -3
  355. package/src/core/components/shadcn/input.tsx +3 -3
  356. package/src/core/components/shadcn/modal/ConfirmModal.tsx +3 -3
  357. package/src/core/components/shadcn/modal/dialog.tsx +2 -4
  358. package/src/core/components/shadcn/overflowTabs.tsx +2 -2
  359. package/src/core/components/shadcn/popover.tsx +1 -1
  360. package/src/core/components/shadcn/radioGroup.tsx +5 -7
  361. package/src/core/components/shadcn/selectBox.tsx +1 -1
  362. package/src/core/components/shadcn/tabs.tsx +4 -2
  363. package/src/core/components/styles.ts +1 -1
  364. package/src/core/components/table/index.tsx +1 -1
  365. package/src/core/hooks/useFetch.test.ts +20 -0
  366. package/src/core/hooks/useFetch.ts +2 -0
  367. package/src/css/base.css +1 -1
  368. package/src/css/color.css +4 -0
  369. package/src/css/theme.css +1 -0
  370. package/src/css/typography.css +2 -2
  371. package/src/features/activity-doc/ActivityDoc.tsx +11 -11
  372. package/src/features/agent/chat/AgentChart.tsx +1 -1
  373. package/src/features/agent/chat/AskUserWidget.tsx +19 -23
  374. package/src/features/agent/chat/JumpingDots.tsx +3 -3
  375. package/src/features/agent/chat/ModernAgentConversation.tsx +3 -3
  376. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +60 -1
  377. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +44 -24
  378. package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +12 -12
  379. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +1 -1
  380. package/src/features/agent/chat/ModernAgentOutput/InlineSlideInPanel.tsx +4 -4
  381. package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +2 -2
  382. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +7 -12
  383. package/src/features/agent/chat/ModernAgentOutput/MessagesContainer.tsx +1 -1
  384. package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +16 -22
  385. package/src/features/agent/chat/ModernAgentOutput/SlideInPanel.tsx +4 -4
  386. package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +2 -4
  387. package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +21 -21
  388. package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +4 -4
  389. package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +16 -1
  390. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +19 -40
  391. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +41 -0
  392. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +19 -0
  393. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +93 -0
  394. package/src/features/agent/chat/SlidingThinkingIndicator.tsx +5 -2
  395. package/src/features/agent/chat/VegaLiteChart.tsx +6 -2
  396. package/src/features/errors/RowErrorBoundary.tsx +1 -1
  397. package/src/features/facets/AgentRunnerFacetsNav.tsx +1 -1
  398. package/src/features/facets/utils/VInteractionFacet.tsx +22 -34
  399. package/src/features/facets/utils/VUserFacet.tsx +1 -1
  400. package/src/features/layout/GenericPageNavHeader.tsx +9 -1
  401. package/src/features/layout/NotFoundView.tsx +1 -1
  402. package/src/features/magic-pdf/AnnotatedImageSlider.tsx +8 -16
  403. package/src/features/magic-pdf/ExtractedContentView.tsx +4 -4
  404. package/src/features/magic-pdf/MagicPdfView.tsx +1 -1
  405. package/src/features/pdf-viewer/PdfPageRenderer.tsx +2 -2
  406. package/src/features/pdf-viewer/PdfPageSlider.tsx +4 -4
  407. package/src/features/pdf-viewer/SimplePdfViewer.tsx +1 -1
  408. package/src/features/permissions/UserPermissionsProvider.test.tsx +172 -0
  409. package/src/features/permissions/UserPermissionsProvider.tsx +68 -21
  410. package/src/features/permissions/useRoleMappings.ts +105 -0
  411. package/src/features/store/collections/SelectCollection.tsx +1 -1
  412. package/src/features/store/objects/DocumentPreviewPanel.tsx +43 -53
  413. package/src/features/store/objects/DocumentTable.tsx +2 -2
  414. package/src/features/store/objects/components/DocumentIcon.tsx +4 -4
  415. package/src/features/store/objects/components/DocumentInput.tsx +3 -3
  416. package/src/features/store/objects/components/PropertiesEditorModal.tsx +2 -2
  417. package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +2 -2
  418. package/src/features/store/objects/layout/documentLayout.tsx +2 -4
  419. package/src/features/store/objects/selection/SelectionActions.tsx +1 -1
  420. package/src/features/store/types/IntakePolicyEditor.tsx +70 -36
  421. package/src/features/store/types/IntakePolicyForm.tsx +11 -3
  422. package/src/features/store/types/SelectContentTypeModal.tsx +1 -1
  423. package/src/features/user/UserAvatar.tsx +3 -3
  424. package/src/features/user/UserInfo.tsx +11 -16
  425. package/src/features/utils/index.ts +1 -0
  426. package/src/features/utils/interaction.test.tsx +93 -0
  427. package/src/features/utils/interaction.tsx +125 -0
  428. package/src/features/views/ViewResults.tsx +3 -3
  429. package/src/i18n/locales/ar.json +7 -1
  430. package/src/i18n/locales/de.json +7 -1
  431. package/src/i18n/locales/en.json +7 -1
  432. package/src/i18n/locales/es.json +7 -1
  433. package/src/i18n/locales/fr.json +7 -1
  434. package/src/i18n/locales/it.json +7 -1
  435. package/src/i18n/locales/ja.json +7 -1
  436. package/src/i18n/locales/ko.json +7 -1
  437. package/src/i18n/locales/pt.json +7 -1
  438. package/src/i18n/locales/ru.json +7 -1
  439. package/src/i18n/locales/tr.json +7 -1
  440. package/src/i18n/locales/zh-TW.json +7 -1
  441. package/src/i18n/locales/zh.json +7 -1
  442. package/src/layout/FullHeightLayout.tsx +2 -2
  443. package/src/layout/Navbar.tsx +5 -5
  444. package/src/layout/Sidebar.tsx +1 -1
  445. package/src/session/UserSessionProvider.tsx +2 -15
  446. package/src/session/auth/authState.test.ts +35 -0
  447. package/src/session/auth/authState.ts +42 -0
  448. package/src/session/auth/domainRouting.test.ts +169 -1
  449. package/src/session/auth/domainRouting.ts +89 -0
  450. package/src/session/auth/useAuthState.ts +5 -49
  451. package/src/session/index.ts +6 -0
  452. package/src/shell/SplashScreen.test.tsx +22 -0
  453. package/src/shell/SplashScreen.tsx +6 -2
  454. package/src/shell/VertesiaShell.tsx +1 -1
  455. package/src/shell/apps/AppProjectSelector.tsx +1 -1
  456. package/src/shell/apps/StandaloneApp.tsx +9 -9
  457. package/src/shell/login/SignInPrimitives.tsx +2 -2
  458. package/src/shell/login/SigninScreen.tsx +1 -1
  459. package/src/shell/login/SignupForm.tsx +2 -2
  460. package/src/shell/login/TerminalLogin.tsx +5 -5
  461. package/src/shell/login/UserInfo.tsx +2 -5
  462. package/src/shell/login/UserSessionMenu.tsx +2 -2
  463. package/src/widgets/Progress.tsx +2 -2
  464. package/src/widgets/form/Form.tsx +4 -4
  465. package/src/widgets/form/fields.tsx +2 -2
  466. package/src/widgets/json-view/JSONView.tsx +1 -6
  467. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +33 -29
  468. package/src/widgets/markdown/MarkdownRenderer.test.tsx +52 -0
  469. package/src/widgets/markdown/MermaidDiagram.tsx +2 -2
  470. package/src/widgets/markdown/remarkDirectiveHandler.ts +21 -5
  471. package/src/widgets/monacoEditor/MonacoEditor.tsx +4 -2
  472. package/src/widgets/monacoEditor/index.ts +1 -0
  473. package/src/widgets/monacoEditor/loadMonaco.test.ts +63 -0
  474. package/src/widgets/monacoEditor/loadMonaco.ts +70 -0
  475. package/src/widgets/properties/PropertiesView.tsx +1 -1
  476. package/src/widgets/schema-editor/editor/Editable.tsx +2 -2
  477. package/src/widgets/schema-editor/editor/PropertyEditor.tsx +1 -1
  478. package/src/widgets/schema-editor/editor/SchemaEditor.tsx +2 -2
  479. package/src/widgets/upload/DropZone.tsx +1 -1
  480. package/src/widgets/upload/UploadResultCategory.tsx +7 -7
  481. package/src/widgets/upload/UploadSummary.tsx +4 -4
  482. package/src/widgets/xml-viewer/components/XMLViewer.tsx +7 -3
  483. package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +60 -7
  484. package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +70 -16
  485. package/lib/vertesia-ui-i18n.3yHWompP.chunk.js +0 -5
  486. package/lib/vertesia-ui-i18n.3yHWompP.chunk.js.map +0 -1
  487. package/lib/vertesia-ui-i18n.4XKCcnL0.chunk.js +0 -5
  488. package/lib/vertesia-ui-i18n.4XKCcnL0.chunk.js.map +0 -1
  489. package/lib/vertesia-ui-i18n.78KG4J25.chunk.js +0 -5
  490. package/lib/vertesia-ui-i18n.78KG4J25.chunk.js.map +0 -1
  491. package/lib/vertesia-ui-i18n.BN06mpp1.chunk.js +0 -5
  492. package/lib/vertesia-ui-i18n.BN06mpp1.chunk.js.map +0 -1
  493. package/lib/vertesia-ui-i18n.CSzKLlHJ.chunk.js +0 -5
  494. package/lib/vertesia-ui-i18n.CSzKLlHJ.chunk.js.map +0 -1
  495. package/lib/vertesia-ui-i18n.Ccus7aRh.chunk.js +0 -5
  496. package/lib/vertesia-ui-i18n.Ccus7aRh.chunk.js.map +0 -1
  497. package/lib/vertesia-ui-i18n.D9j3c6gI.chunk.js +0 -5
  498. package/lib/vertesia-ui-i18n.D9j3c6gI.chunk.js.map +0 -1
  499. package/lib/vertesia-ui-i18n.DAUg4rrI.chunk.js +0 -5
  500. package/lib/vertesia-ui-i18n.DAUg4rrI.chunk.js.map +0 -1
  501. package/lib/vertesia-ui-i18n.DSxVZKXy.chunk.js +0 -5
  502. package/lib/vertesia-ui-i18n.DSxVZKXy.chunk.js.map +0 -1
  503. package/lib/vertesia-ui-i18n.aahVhHvR.chunk.js +0 -5
  504. package/lib/vertesia-ui-i18n.aahVhHvR.chunk.js.map +0 -1
  505. package/lib/vertesia-ui-i18n.nZ3xJ26v.chunk.js +0 -5
  506. package/lib/vertesia-ui-i18n.nZ3xJ26v.chunk.js.map +0 -1
  507. package/lib/vertesia-ui-i18n.xPYbuFzT.chunk.js +0 -5
  508. package/lib/vertesia-ui-i18n.xPYbuFzT.chunk.js.map +0 -1
@@ -1,7 +1,12 @@
1
- import { afterEach, describe, expect, it } from 'vitest';
1
+ import { Env } from '@vertesia/ui/env';
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
3
  import {
3
4
  centralAuthRedirectUrl,
5
+ clearCentralAuthRoundTripMarker,
6
+ isCentralAuthRedirectPending,
7
+ markCentralAuthRoundTripStarted,
4
8
  mountRootUrl,
9
+ redirectToCentralAuth,
5
10
  shouldRedirectToCentralAuth,
6
11
  shouldUseFirebaseAuth,
7
12
  } from './domainRouting';
@@ -74,3 +79,166 @@ describe('domainRouting', () => {
74
79
  });
75
80
  });
76
81
  });
82
+
83
+ // The boot-time counterpart of the redirect UserSessionProvider performs after mounting. It must
84
+ // answer true only when that provider is certain to redirect, because an app's entry module skips
85
+ // the whole React tree on the strength of it -- and false whenever the answer is not certain, which
86
+ // only costs the (current) wasted boot.
87
+ describe('isCentralAuthRedirectPending', () => {
88
+ function initEnv(props: {
89
+ isLocalDev?: boolean;
90
+ devAuthToken?: string;
91
+ authTokenProvider?: () => Promise<string>;
92
+ }) {
93
+ Env.init({
94
+ name: 'test',
95
+ version: '0',
96
+ isDocker: false,
97
+ type: 'development',
98
+ isLocalDev: props.isLocalDev ?? false,
99
+ devAuthToken: props.devAuthToken,
100
+ authTokenProvider: props.authTokenProvider,
101
+ endpoints: { studio: 'https://studio.test', zeno: 'https://zeno.test', sts: 'https://sts.test' },
102
+ });
103
+ }
104
+
105
+ function setLocation(hash: string) {
106
+ (globalThis as { window?: unknown }).window = { AUTH_MODE: 'central', location: { hash } };
107
+ }
108
+
109
+ afterEach(() => {
110
+ delete (globalThis as { window?: unknown }).window;
111
+ });
112
+
113
+ it('is true for a plain cold load in central-auth mode', () => {
114
+ initEnv({});
115
+ setLocation('');
116
+ expect(isCentralAuthRedirectPending()).toBe(true);
117
+ });
118
+
119
+ it('is false when AUTH_MODE is firebase, which signs in without the broker', () => {
120
+ initEnv({});
121
+ (globalThis as { window?: unknown }).window = { AUTH_MODE: 'firebase', location: { hash: '' } };
122
+ expect(isCentralAuthRedirectPending()).toBe(false);
123
+ });
124
+
125
+ it('is false on the return leg carrying both token and state', () => {
126
+ initEnv({});
127
+ setLocation('#token=abc&state=xyz');
128
+ expect(isCentralAuthRedirectPending()).toBe(false);
129
+ });
130
+
131
+ // A hash with only one half of the pair is not a usable return leg: UserSessionProvider falls
132
+ // through to a fresh redirect, so the shortcut must agree.
133
+ it('is true when the hash carries a token but no state', () => {
134
+ initEnv({});
135
+ setLocation('#token=abc');
136
+ expect(isCentralAuthRedirectPending()).toBe(true);
137
+ });
138
+
139
+ it('is true when the hash carries a state but no token', () => {
140
+ initEnv({});
141
+ setLocation('#state=xyz');
142
+ expect(isCentralAuthRedirectPending()).toBe(true);
143
+ });
144
+
145
+ it('is false when a host app injects a token provider', () => {
146
+ initEnv({ authTokenProvider: async () => 'injected' });
147
+ setLocation('');
148
+ expect(isCentralAuthRedirectPending()).toBe(false);
149
+ });
150
+
151
+ it('is false in local development with a dev auth token', () => {
152
+ initEnv({ isLocalDev: true, devAuthToken: 'dev-token' });
153
+ setLocation('');
154
+ expect(isCentralAuthRedirectPending()).toBe(false);
155
+ });
156
+
157
+ it('is true in local development without a dev auth token', () => {
158
+ initEnv({ isLocalDev: true });
159
+ setLocation('');
160
+ expect(isCentralAuthRedirectPending()).toBe(true);
161
+ });
162
+ });
163
+
164
+ // The marker exists for a server that generates the page: it is the only way to tell the leg that
165
+ // is about to redirect from the leg that came back, since the token returns in the URL fragment and
166
+ // never reaches a server. Its exact attributes are the contract -- a cookie the browser refuses to
167
+ // store, or one that is not sent on the top-level navigation back from the broker, degrades to "no
168
+ // marker" silently and costs a round-trip on every load instead.
169
+ describe('central auth round-trip marker', () => {
170
+ function setProtocol(protocol: string): { cookie: string } {
171
+ const document = { cookie: '' };
172
+ (globalThis as { window?: unknown }).window = { location: { protocol } };
173
+ (globalThis as { document?: unknown }).document = document;
174
+ return document;
175
+ }
176
+
177
+ afterEach(() => {
178
+ delete (globalThis as { window?: unknown }).window;
179
+ delete (globalThis as { document?: unknown }).document;
180
+ });
181
+
182
+ it('sets a short-lived, root-scoped cookie that survives the navigation back from the broker', () => {
183
+ const document = setProtocol('https:');
184
+ markCentralAuthRoundTripStarted();
185
+ // Lax, not Strict: the return leg is a cross-site top-level GET, which Strict would drop.
186
+ expect(document.cookie).toBe('vtsauth=1; Path=/; Max-Age=300; SameSite=Lax; Secure');
187
+ });
188
+
189
+ it('omits Secure over http so local development keeps the marker', () => {
190
+ const document = setProtocol('http:');
191
+ markCentralAuthRoundTripStarted();
192
+ expect(document.cookie).toBe('vtsauth=1; Path=/; Max-Age=300; SameSite=Lax');
193
+ });
194
+
195
+ it('expires the cookie on the same path when the app mounts', () => {
196
+ const document = setProtocol('https:');
197
+ clearCentralAuthRoundTripMarker();
198
+ // Same name and Path, or the browser keeps the original cookie alongside this one.
199
+ expect(document.cookie).toBe('vtsauth=; Path=/; Max-Age=0; SameSite=Lax; Secure');
200
+ });
201
+ });
202
+
203
+ // The shared redirect must preserve release/1.5's gateway selection and write state that
204
+ // the provider's hook accepts when the broker returns.
205
+ describe('redirectToCentralAuth', () => {
206
+ afterEach(() => {
207
+ vi.unstubAllGlobals();
208
+ sessionStorage.clear();
209
+ Env.init();
210
+ });
211
+
212
+ it('keeps the gateway mount and selection, records state, and marks the round trip before navigating', async () => {
213
+ const { verifyAuthState, clearAuthState } = await import('./authState');
214
+ const mount = 'https://apps.test/tenants/t/apps/a/versions/v/app/';
215
+ const document = { baseURI: mount, cookie: '' };
216
+ const replace = vi.fn((target: string) => {
217
+ const url = new URL(target);
218
+ expect(document.cookie).toBe('vtsauth=1; Path=/; Max-Age=300; SameSite=Lax; Secure');
219
+ expect(verifyAuthState(url.searchParams.get('state'))).toBeUndefined();
220
+ });
221
+ vi.stubGlobal('window', { location: { href: 'https://apps.test/?view=grid#old', protocol: 'https:' } });
222
+ vi.stubGlobal('document', document);
223
+ vi.stubGlobal('location', { replace });
224
+ Env.init({
225
+ name: 'test',
226
+ version: '0',
227
+ isLocalDev: false,
228
+ isDocker: false,
229
+ type: 'production',
230
+ endpoints: { studio: 'https://studio.test', zeno: 'https://zeno.test', sts: 'https://sts.test/?x=1&y=2' },
231
+ });
232
+
233
+ redirectToCentralAuth({ accountId: 'account-1', projectId: 'project-1' });
234
+
235
+ expect(replace).toHaveBeenCalledOnce();
236
+ const url = new URL(replace.mock.calls[0][0]);
237
+ expect(url.origin).toBe('https://internal-auth.vertesia.app');
238
+ expect(url.searchParams.get('sts')).toBe('https://sts.test/?x=1&y=2');
239
+ expect(url.searchParams.get('redirect_uri')).toBe(`${mount}?p=project-1&a=account-1`);
240
+ expect(verifyAuthState('wrong')).toContain('State mismatched');
241
+ clearAuthState();
242
+ expect(verifyAuthState(url.searchParams.get('state'))).toContain('State mismatched');
243
+ });
244
+ });
@@ -1,3 +1,6 @@
1
+ import { Env } from '@vertesia/ui/env';
2
+ import { generateAuthState } from './authState';
3
+
1
4
  declare global {
2
5
  interface Window {
3
6
  AUTH_MODE?: 'firebase' | 'central';
@@ -78,3 +81,89 @@ export function mountRootUrl(): URL {
78
81
  url.search = '';
79
82
  return url;
80
83
  }
84
+
85
+ /**
86
+ * A short-lived marker saying "a Central Auth round-trip is in flight for this browser".
87
+ *
88
+ * It exists for the server that generates index.html. Preload hints are markup, so they start
89
+ * fetching before any script runs: a page load that is going to bounce off to the broker cannot
90
+ * avoid downloading the application by any decision made in the page itself. The server can, but
91
+ * only if it can tell the outgoing leg from the return leg -- and the token comes back in the URL
92
+ * *fragment*, which a server never sees. Hence a cookie: set here, immediately before navigating to
93
+ * the broker, and cleared by the app as soon as it mounts.
94
+ *
95
+ * It carries no identity and grants nothing; it is a hint about which of two page loads this is.
96
+ * The TTL bounds the cost of the case where the app never mounts (the visitor abandons the login
97
+ * screen): after it lapses, cold loads are back to withholding the application preloads.
98
+ */
99
+ const AUTH_ROUND_TRIP_COOKIE = 'vtsauth';
100
+ const AUTH_ROUND_TRIP_TTL_SECONDS = 300;
101
+
102
+ function authRoundTripCookie(value: string, maxAgeSeconds: number): string {
103
+ // Secure only over https: setting it on http://localhost would make the browser drop the
104
+ // cookie, and local development would silently lose the return-leg preloads.
105
+ const secure = window.location.protocol === 'https:' ? '; Secure' : '';
106
+ return `${AUTH_ROUND_TRIP_COOKIE}=${value}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${secure}`;
107
+ }
108
+
109
+ /** Record that this browser is on its way to the broker. Called for you by {@link redirectToCentralAuth}. */
110
+ export function markCentralAuthRoundTripStarted(): void {
111
+ // biome-ignore lint/suspicious/noDocumentCookie: CookieStore is async; this must land before location.replace()
112
+ document.cookie = authRoundTripCookie('1', AUTH_ROUND_TRIP_TTL_SECONDS);
113
+ }
114
+
115
+ /**
116
+ * Drop the marker. An app calls this once it is actually rendering, so that its *next* cold load is
117
+ * recognized as an outgoing leg again and does not preload an application it is about to discard.
118
+ */
119
+ export function clearCentralAuthRoundTripMarker(): void {
120
+ // biome-ignore lint/suspicious/noDocumentCookie: pairs with the write above; see that comment.
121
+ document.cookie = authRoundTripCookie('', 0);
122
+ }
123
+
124
+ /**
125
+ * Start a Central Auth round-trip for the current page.
126
+ *
127
+ * The single place the broker URL is assembled, so the boot-time shortcut in an app's entry module
128
+ * and {@link isCentralAuthRedirectPending}'s counterpart inside `UserSessionProvider` cannot drift
129
+ * into producing different `redirect_uri` / `state` / `sts` values for the same page load.
130
+ */
131
+ export function redirectToCentralAuth(selection: { accountId?: string; projectId?: string } = {}): void {
132
+ const url = centralAuthRedirectUrl({
133
+ centralAuthUrl: 'https://internal-auth.vertesia.app/',
134
+ stsEndpoint: Env.endpoints.sts ?? 'https://sts.vertesia.io',
135
+ returnUrl: authReturnUrl(),
136
+ state: generateAuthState(),
137
+ ...selection,
138
+ });
139
+ markCentralAuthRoundTripStarted();
140
+ location.replace(url.toString());
141
+ }
142
+
143
+ /**
144
+ * Whether this page load is already certain to end in a Central Auth round-trip, decidable before
145
+ * any application module has run.
146
+ *
147
+ * A fresh `UserSession` holds no token and nothing persists one across loads, so on a cold load
148
+ * `session.isLoggedIn()` in `UserSessionProvider` is always false. Every condition that can keep
149
+ * that provider from redirecting is therefore knowable up front, and this predicate enumerates
150
+ * them in the same order:
151
+ *
152
+ * - Apps configured with Firebase auth sign in in place rather than at the broker;
153
+ * - a host app that injects a token through `Env.authTokenProvider` may not need the broker
154
+ * (and when its token turns out to be empty the provider still redirects — answering `false`
155
+ * here just lets the normal flow decide, which is the safe direction);
156
+ * - local development with a configured dev token skips auth entirely;
157
+ * - a load carrying `#token=…&state=…` *is* the return leg and must be allowed to exchange it.
158
+ *
159
+ * When this returns true the app is going to navigate away, so an entry module can redirect
160
+ * immediately instead of mounting a full React tree, initializing telemetry and warming route
161
+ * chunks that the navigation is about to discard.
162
+ */
163
+ export function isCentralAuthRedirectPending(): boolean {
164
+ if (!shouldRedirectToCentralAuth()) return false;
165
+ if (Env.authTokenProvider) return false;
166
+ if (Env.isLocalDev && Env.devAuthToken) return false;
167
+ const hashParams = new URLSearchParams(window.location.hash.substring(1));
168
+ return !(hashParams.get('token') && hashParams.get('state'));
169
+ }
@@ -1,54 +1,10 @@
1
- /**
2
- * This hook is used to generate and verify state for OAuth2 authorization requests.
3
- * @returns
4
- */
5
-
1
+ /** React wrappers for the state record shared with boot-time Central Auth redirects. */
6
2
  import { useCallback } from 'react';
7
-
8
- const AUTH_STATE_KEY = 'auth_state';
9
- const STATE_EXPIRY_KEY = 'auth_state_expiry';
10
- const STATE_TTL = 5 * 60 * 1000; // 5 min
3
+ import { clearAuthState, generateAuthState, verifyAuthState } from './authState';
11
4
 
12
5
  export function useAuthState() {
13
- // Generate new state
14
- const generateState = useCallback(() => {
15
- const state = crypto.randomUUID();
16
- const expiryTime = Date.now() + STATE_TTL;
17
-
18
- // Store state and expiry
19
- sessionStorage.setItem(AUTH_STATE_KEY, state);
20
- sessionStorage.setItem(STATE_EXPIRY_KEY, expiryTime.toString());
21
-
22
- return state;
23
- }, []);
24
-
25
- // Verify returned state
26
- const verifyState = useCallback((returnedState: string | null): string | undefined => {
27
- if (!returnedState) {
28
- return 'Missing state';
29
- }
30
-
31
- const savedState = sessionStorage.getItem(AUTH_STATE_KEY);
32
- const expiryTime = parseInt(sessionStorage.getItem(STATE_EXPIRY_KEY) || '0', 10);
33
- let reason: string | undefined;
34
-
35
- // Verify state matches and hasn't expired
36
- if (savedState !== returnedState) {
37
- reason = `State mismatched (${savedState} !== ${returnedState})`;
38
- } else if (Date.now() > expiryTime) {
39
- reason = 'State expired';
40
- } else {
41
- reason = undefined; // No errors
42
- }
43
-
44
- return reason;
45
- }, []);
46
-
47
- // Clear state (useful for cleanup)
48
- const clearState = useCallback(() => {
49
- sessionStorage.removeItem(AUTH_STATE_KEY);
50
- sessionStorage.removeItem(STATE_EXPIRY_KEY);
51
- }, []);
52
-
6
+ const generateState = useCallback(generateAuthState, []);
7
+ const verifyState = useCallback(verifyAuthState, []);
8
+ const clearState = useCallback(clearAuthState, []);
53
9
  return { generateState, verifyState, clearState };
54
10
  }
@@ -1,4 +1,10 @@
1
1
  export * from './auth/composable';
2
+ // Publish the boot-time auth entry points.
3
+ export {
4
+ clearCentralAuthRoundTripMarker,
5
+ isCentralAuthRedirectPending,
6
+ redirectToCentralAuth,
7
+ } from './auth/domainRouting';
2
8
  export * from './auth/firebase';
3
9
  export * from './auth/useAuthState';
4
10
  export * from './auth/useCurrentTenant';
@@ -0,0 +1,22 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import type { AuthTokenPayload } from '@vertesia/common';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import { SplashScreen } from './SplashScreen';
5
+
6
+ const session = { isLoading: true, authToken: undefined as AuthTokenPayload | undefined };
7
+ vi.mock('@vertesia/ui/session', () => ({ useUserSession: () => session }));
8
+
9
+ describe('SplashScreen handoff', () => {
10
+ it.each([true, false])('removes the splash immediately when a token arrives with isLoading=%s', (isLoading) => {
11
+ session.isLoading = true;
12
+ session.authToken = undefined;
13
+ const view = render(<SplashScreen icon={<span>Startup indicator</span>} />);
14
+ expect(screen.getByText('Startup indicator')).toBeTruthy();
15
+
16
+ session.isLoading = isLoading;
17
+ session.authToken = {} as AuthTokenPayload;
18
+ view.rerender(<SplashScreen icon={<span>Startup indicator</span>} />);
19
+ // No fading splash remains over the permission gate's connection screen.
20
+ expect(screen.queryByText('Startup indicator')).toBeNull();
21
+ });
22
+ });
@@ -6,7 +6,7 @@ interface SplashScreenProps {
6
6
  icon?: ReactNode;
7
7
  }
8
8
  export function SplashScreen({ icon: Icon }: SplashScreenProps) {
9
- const { isLoading } = useUserSession();
9
+ const { isLoading, authToken } = useUserSession();
10
10
  const [show, setShow] = useState(true);
11
11
 
12
12
  useEffect(() => {
@@ -15,6 +15,10 @@ export function SplashScreen({ icon: Icon }: SplashScreenProps) {
15
15
  }
16
16
  }, [isLoading]);
17
17
 
18
+ // The permission gate owns the loading UI once a token is available.
19
+ // Skip the exit animation too, so two loading indicators never overlap.
20
+ if (authToken) return null;
21
+
18
22
  return (
19
23
  <AnimatePresence>
20
24
  {show && (
@@ -54,7 +58,7 @@ function LoadingIcon() {
54
58
  <svg
55
59
  width="32"
56
60
  height="32"
57
- className="w-8 h-8 text-indigo-600"
61
+ className="w-8 h-8 text-primary"
58
62
  viewBox="0 0 50 50"
59
63
  xmlns="http://www.w3.org/2000/svg"
60
64
  role="img"
@@ -49,7 +49,7 @@ export function VertesiaShell({
49
49
  />
50
50
  </>
51
51
  )}
52
- <UserPermissionProvider>{children}</UserPermissionProvider>
52
+ <UserPermissionProvider loadingIcon={loadingIcon}>{children}</UserPermissionProvider>
53
53
  </LanguageBoundI18nProvider>
54
54
  </LanguageProvider>
55
55
  </ThemeProvider>
@@ -29,7 +29,7 @@ export function AppProjectSelector({ app, onChange, placeholder }: AppProjectSel
29
29
  };
30
30
 
31
31
  if (error) {
32
- return <span className="text-red-600">Error: failed to fetch projects: {errorMessage(error)}</span>;
32
+ return <span className="text-destructive">Error: failed to fetch projects: {errorMessage(error)}</span>;
33
33
  }
34
34
  return (
35
35
  <SelectProject
@@ -116,15 +116,15 @@ function AccessDeniedMessage({ name }: AccessDeniedMessageProps) {
116
116
  const selectedOrg = orgOptions.find((a) => a.id === selectedAccountId);
117
117
 
118
118
  return (
119
- <Center className="pt-10 flex flex-col items-center text-center text-gray-700">
120
- <LockIcon className="w-10 h-10 mb-4 text-gray-500" />
119
+ <Center className="pt-10 flex flex-col items-center text-center text-foreground">
120
+ <LockIcon className="w-10 h-10 mb-4 text-muted" />
121
121
  <div className="text-xl font-semibold">{t('shell.accessDenied')}</div>
122
- <div className="mt-2 text-sm text-gray-500">
122
+ <div className="mt-2 text-sm text-muted">
123
123
  You don&apos;t have permission to view the <span className="font-semibold">{name}</span> app in project:{' '}
124
124
  <span className="font-semibold">&laquo;{project?.name}&raquo;</span>.
125
125
  </div>
126
126
  {orgOptions.length === 0 && allProjects !== undefined && (
127
- <div className="mt-4 text-sm text-gray-500">
127
+ <div className="mt-4 text-sm text-muted">
128
128
  This app is not installed in any project you have access to.
129
129
  </div>
130
130
  )}
@@ -132,7 +132,7 @@ function AccessDeniedMessage({ name }: AccessDeniedMessageProps) {
132
132
  <div className="mt-4 flex flex-row gap-4 items-end">
133
133
  {orgOptions.length > 1 && (
134
134
  <div>
135
- <div className="text-sm text-gray-500 mb-2">{t('shell.organization')}</div>
135
+ <div className="text-sm text-muted mb-2">{t('shell.organization')}</div>
136
136
  <SelectBox
137
137
  by="id"
138
138
  value={selectedOrg}
@@ -145,7 +145,7 @@ function AccessDeniedMessage({ name }: AccessDeniedMessageProps) {
145
145
  )}
146
146
  <div>
147
147
  {orgOptions.length > 1 && (
148
- <div className="text-sm text-gray-500 mb-2">{t('login.terminal.project')}</div>
148
+ <div className="text-sm text-muted mb-2">{t('login.terminal.project')}</div>
149
149
  )}
150
150
  <SelectBox
151
151
  by="id"
@@ -165,10 +165,10 @@ function AccessDeniedMessage({ name }: AccessDeniedMessageProps) {
165
165
  function UnknownAppName() {
166
166
  const { t } = useUITranslation();
167
167
  return (
168
- <Center className="pt-10 flex flex-col items-center text-center text-gray-700">
169
- <LockIcon className="w-10 h-10 mb-4 text-gray-500" />
168
+ <Center className="pt-10 flex flex-col items-center text-center text-foreground">
169
+ <LockIcon className="w-10 h-10 mb-4 text-muted" />
170
170
  <div className="text-xl font-semibold">{t('shell.applicationNotRegistered')}</div>
171
- <div className="mt-2 text-sm text-gray-500">
171
+ <div className="mt-2 text-sm text-muted">
172
172
  Before starting to code a Vertesia application you must register an application manifest in Vertesia
173
173
  Studio then install it in one or more projects.
174
174
  <p />
@@ -355,7 +355,7 @@ export function SignInCallout({ icon: Icon, title, meta }: SignInCalloutProps) {
355
355
  /** Horizontal rule with a centered label. */
356
356
  export function SignInOrDivider({ children }: { children: ReactNode }) {
357
357
  return (
358
- <div className="flex items-center gap-3 my-2 text-muted-foreground text-[10.5px] uppercase tracking-widest">
358
+ <div className="flex items-center gap-3 my-2 text-muted text-[10.5px] uppercase tracking-widest">
359
359
  <div className="flex-1 h-px bg-border" />
360
360
  <span>{children}</span>
361
361
  <div className="flex-1 h-px bg-border" />
@@ -393,7 +393,7 @@ export function SignInEmailField({
393
393
  id="vt-login-email"
394
394
  name="vt-login-email"
395
395
  type="email"
396
- className="h-[42px] px-3.5 rounded-md border border-border bg-background text-sm text-foreground placeholder:text-muted-foreground outline-none transition focus:border-info focus:ring-4 focus:ring-info/15 aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-destructive/15"
396
+ className="h-[42px] px-3.5 rounded-md border border-border bg-background text-sm text-foreground placeholder:text-muted outline-none transition focus:border-info focus:ring-4 focus:ring-info/15 aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-destructive/15"
397
397
  placeholder={placeholder}
398
398
  value={value}
399
399
  onChange={(e) => onChange(e.target.value)}
@@ -385,7 +385,7 @@ function SigninScreenImpl({
385
385
  </div>
386
386
  )}
387
387
 
388
- <div className="flex items-center gap-5 mt-10 text-xs text-muted-foreground">
388
+ <div className="flex items-center gap-5 mt-10 text-xs text-muted">
389
389
  <a href="https://vertesiahq.com/privacy" className="hover:text-foreground transition">
390
390
  {t('auth.privacyPolicy')}
391
391
  </a>
@@ -126,7 +126,7 @@ export default function SignupForm({ onSignup, goBack }: SignupFormProps) {
126
126
  <>
127
127
  <FormItem label={t('signup.companySize')}>
128
128
  <SelectBox
129
- className="w-full border border-accent bg-muted"
129
+ className="w-full border border-muted bg-muted"
130
130
  value={companySize}
131
131
  options={companySizeOptions}
132
132
  onChange={setCompanySize}
@@ -144,7 +144,7 @@ export default function SignupForm({ onSignup, goBack }: SignupFormProps) {
144
144
  )}
145
145
  <FormItem label={t('signup.projectMaturity')}>
146
146
  <SelectBox
147
- className="w-full border border-accent bg-muted"
147
+ className="w-full border border-muted bg-muted"
148
148
  options={projectMaturityOptions}
149
149
  value={projectMaturityOptions.find((option) => option.id === projectMaturity)}
150
150
  optionLabel={(option) => option?.label}
@@ -220,14 +220,14 @@ function AuthAcceptScreen({ onAccept, clientInfo }: Readonly<AuthAcceptScreenPro
220
220
  <>
221
221
  <div className="w-1/3">
222
222
  <div className="mb-4 text-xl font-semibold text-info">Authorizing client on {envName} environment.</div>
223
- <div className="mb-2 text-md text-muted-foreground">
223
+ <div className="mb-2 text-base text-muted">
224
224
  <div>{t('login.terminal.clientWantsAuth')}</div>
225
225
  <div>
226
226
  The client app code is <b className="text-foreground">{clientInfo.code}</b>. You can check if
227
227
  the code is correct in the terminal.
228
228
  </div>
229
229
  </div>
230
- <div className="mb-2 text-sm text-muted-foreground">
230
+ <div className="mb-2 text-sm text-muted">
231
231
  <div>{t('login.terminal.chooseAccountProject')}</div>
232
232
  <div>{t('login.terminal.profileNameNote')}</div>
233
233
  </div>
@@ -307,15 +307,15 @@ function ProfileForm({ allProjects, data, onAccept }: Readonly<ProfileFormProps>
307
307
  return (
308
308
  <div className="w-1/3">
309
309
  <div className="mb-4 flex flex-col gap-2">
310
- <span className="font-semibold text-muted-foreground">{t('login.terminal.profileName')}</span>
310
+ <span className="font-semibold text-muted">{t('login.terminal.profileName')}</span>
311
311
  <Input type="text" value={currentData.profile} onChange={onChangeProfile} />
312
312
  </div>
313
313
  <div className="mb-4 flex flex-col gap-2">
314
- <span className="font-semibold text-muted-foreground">{t('login.terminal.account')}</span>
314
+ <span className="font-semibold text-muted">{t('login.terminal.account')}</span>
315
315
  <SelectAccount value={currentData.account} onChange={onChangeAccount} accounts={accounts || []} />
316
316
  </div>
317
317
  <div className="mb-4 flex flex-col gap-2">
318
- <span className="font-semibold text-muted-foreground">{t('login.terminal.project')}</span>
318
+ <span className="font-semibold text-muted">{t('login.terminal.project')}</span>
319
319
  <SelectProject value={currentData.project} onChange={onChangeProject} projects={projects} />
320
320
  </div>
321
321
  <div className="mb-4 text-sm text-attention">{t('login.terminal.browserPermissionNote')}</div>
@@ -17,7 +17,7 @@ export function InfoItems({ title, value }: { title: string; value: string }) {
17
17
  return (
18
18
  <div className="w-full flex justify-between items-center mb-1">
19
19
  <div className="flex flex-col w-[calc(100%-3rem)]">
20
- <div className="text-sm px-2 dark:text-slate-200">{title}</div>
20
+ <div className="text-sm px-2 dark:text-foreground">{title}</div>
21
21
  <VTooltip description={value} size="xs" placement="left">
22
22
  <div className="text-xs truncate text-muted w-full text-start px-2">{value} </div>
23
23
  </VTooltip>
@@ -25,10 +25,7 @@ export function InfoItems({ title, value }: { title: string; value: string }) {
25
25
  {isCopied ? (
26
26
  <Check className="size-4 cursor-pointer text-success" />
27
27
  ) : (
28
- <CopyIcon
29
- className="size-4 cursor-pointer text-gray-400 dark:text-slate-400"
30
- onClick={() => copyToClipboard(value)}
31
- />
28
+ <CopyIcon className="size-4 cursor-pointer text-muted" onClick={() => copyToClipboard(value)} />
32
29
  )}
33
30
  </div>
34
31
  );
@@ -71,10 +71,10 @@ function UserSessionPopup({ className, asMenuTrigger = false }: UserSessionPopup
71
71
  </div>
72
72
  </PopoverTrigger>
73
73
  <PopoverContent align="start" className="w-[280px] mx-2 my-1 p-0">
74
- <div className="divide-y divide-gray-200 dark:divide-slate-700">
74
+ <div className="divide-y divide-border">
75
75
  <div className="py-2 ps-2">
76
76
  <p className="px-4 dark:text-white mb-1">{user?.name ?? 'Unknown'}</p>
77
- <p className="px-4 text-xs text-gray-500">{user?.email ?? ''}</p>
77
+ <p className="px-4 text-xs text-muted">{user?.email ?? ''}</p>
78
78
  </div>
79
79
  <div className="w-full p-1">
80
80
  <InfoList />
@@ -3,8 +3,8 @@ interface ProgressProps {
3
3
  }
4
4
  export function Progress({ percent }: ProgressProps) {
5
5
  return (
6
- <div className="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
7
- <div className="bg-blue-600 h-2.5 rounded-full" style={{ width: `${percent}%` }}></div>
6
+ <div className="w-full bg-muted rounded-full h-2.5">
7
+ <div className="bg-primary h-2.5 rounded-full" style={{ width: `${percent}%` }}></div>
8
8
  </div>
9
9
  );
10
10
  }
@@ -120,8 +120,8 @@ interface ObjectFormProps {
120
120
  }
121
121
  function CompositeField({ object }: ObjectFormProps) {
122
122
  return (
123
- <div className="flex flex-col gap-4 my-4 py-2 ps-4 border-s-4 border-s-solid border-s-slate-100 dark:border-s-slate-600">
124
- {!object.isListItem && <div className="text-gray-900 dark:text-gray-200 font-semibold">{object.title}</div>}
123
+ <div className="flex flex-col gap-4 my-4 py-2 ps-4 border-s-4 border-s-solid border-s-border">
124
+ {!object.isListItem && <div className="text-foreground font-semibold">{object.title}</div>}
125
125
  {object.properties.map(renderProperty)}
126
126
  </div>
127
127
  );
@@ -150,8 +150,8 @@ function ListField({ object }: ListFieldProps) {
150
150
  };
151
151
 
152
152
  return (
153
- <div className="flex flex-col gap-4 my-4 py-2 ps-4 border-s-4 border-s-solid border-s-slate-100 darK:border-s-slate-600">
154
- {!object.isListItem && <div className="text-gray-900 dark:text-gray-200 font-semibold">{object.title}</div>}
153
+ <div className="flex flex-col gap-4 my-4 py-2 ps-4 border-s-4 border-s-solid border-s-border darK:border-s-border">
154
+ {!object.isListItem && <div className="text-foreground font-semibold">{object.title}</div>}
155
155
  {object.items.map((item, index) => {
156
156
  const rowId = rowIds[index];
157
157
  return (
@@ -17,12 +17,12 @@ interface FormHelperProps {
17
17
  children: React.ReactNode | React.ReactNode[];
18
18
  }
19
19
  export function FormHelper({ children }: FormHelperProps) {
20
- return <p className="mt-2 text-sm text-gray-500">{children}</p>;
20
+ return <p className="mt-2 text-sm text-muted">{children}</p>;
21
21
  }
22
22
 
23
23
  interface FormErrorProps {
24
24
  children: React.ReactNode | React.ReactNode[];
25
25
  }
26
26
  export function FormError({ children }: FormErrorProps) {
27
- return <p className="mt-2 text-sm text-red-600">{children}</p>;
27
+ return <p className="mt-2 text-sm text-destructive">{children}</p>;
28
28
  }