@vertesia/ui 0.66.0 → 0.68.0

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 (288) hide show
  1. package/lib/esm/core/components/Badge.js +1 -1
  2. package/lib/esm/core/components/Badge.js.map +1 -1
  3. package/lib/esm/core/components/FormItem.js +2 -2
  4. package/lib/esm/core/components/FormItem.js.map +1 -1
  5. package/lib/esm/core/components/InputList.js +2 -2
  6. package/lib/esm/core/components/InputList.js.map +1 -1
  7. package/lib/esm/core/components/shadcn/checkbox.js +1 -1
  8. package/lib/esm/core/components/shadcn/checkbox.js.map +1 -1
  9. package/lib/esm/core/components/shadcn/command.js +1 -1
  10. package/lib/esm/core/components/shadcn/command.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/dialog.js +6 -6
  12. package/lib/esm/core/components/shadcn/dialog.js.map +1 -1
  13. package/lib/esm/core/components/shadcn/filters/DynamicLabel.js.map +1 -1
  14. package/lib/esm/core/components/shadcn/filters/comboBox/DateCombobox.js +129 -0
  15. package/lib/esm/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -0
  16. package/lib/esm/core/components/shadcn/filters/comboBox/SelectCombobox.js +46 -0
  17. package/lib/esm/core/components/shadcn/filters/comboBox/SelectCombobox.js.map +1 -0
  18. package/lib/esm/core/components/shadcn/filters/comboBox/StringListCombobox.js +23 -0
  19. package/lib/esm/core/components/shadcn/filters/comboBox/StringListCombobox.js.map +1 -0
  20. package/lib/esm/core/components/shadcn/filters/comboBox/TextCombobox.js +28 -0
  21. package/lib/esm/core/components/shadcn/filters/comboBox/TextCombobox.js.map +1 -0
  22. package/lib/esm/core/components/shadcn/filters/comboBox/comboBox.js +5 -0
  23. package/lib/esm/core/components/shadcn/filters/comboBox/comboBox.js.map +1 -0
  24. package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js +101 -0
  25. package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js.map +1 -0
  26. package/lib/esm/core/components/shadcn/filters/{stringListFilter.js → filter/StringListFilter.js} +3 -3
  27. package/lib/esm/core/components/shadcn/filters/filter/StringListFilter.js.map +1 -0
  28. package/lib/esm/core/components/shadcn/filters/{textFilter.js → filter/TextFilter.js} +4 -4
  29. package/lib/esm/core/components/shadcn/filters/filter/TextFilter.js.map +1 -0
  30. package/lib/esm/core/components/shadcn/filters/filter/dateFilter.js +161 -0
  31. package/lib/esm/core/components/shadcn/filters/filter/dateFilter.js.map +1 -0
  32. package/lib/esm/core/components/shadcn/filters/filter-styles.js +88 -0
  33. package/lib/esm/core/components/shadcn/filters/filter-styles.js.map +1 -0
  34. package/lib/esm/core/components/shadcn/filters/filterBar.js +128 -87
  35. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  36. package/lib/esm/core/components/shadcn/filters/filters.js +7 -6
  37. package/lib/esm/core/components/shadcn/filters/filters.js.map +1 -1
  38. package/lib/esm/core/components/shadcn/filters/index.js +1 -1
  39. package/lib/esm/core/components/shadcn/filters/index.js.map +1 -1
  40. package/lib/esm/core/components/shadcn/filters/types.js.map +1 -1
  41. package/lib/esm/core/components/toast/NotificationPanel.js +24 -18
  42. package/lib/esm/core/components/toast/NotificationPanel.js.map +1 -1
  43. package/lib/esm/features/agent/PayloadBuilder.js +47 -27
  44. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  45. package/lib/esm/features/agent/chat/ModernAgentConversation.js +10 -4
  46. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  47. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +7 -6
  48. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  49. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +13 -2
  50. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  51. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingMessages.js +2 -1
  52. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingMessages.js.map +1 -1
  53. package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js +10 -4
  54. package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  55. package/lib/esm/features/facets/DocumentsFacetsNav.js +133 -0
  56. package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -0
  57. package/lib/esm/features/facets/RunsFacetsNav.js +125 -0
  58. package/lib/esm/features/facets/RunsFacetsNav.js.map +1 -0
  59. package/lib/esm/features/facets/VFacetsNav.js +4 -113
  60. package/lib/esm/features/facets/VFacetsNav.js.map +1 -1
  61. package/lib/esm/features/facets/VStringFacet.js +6 -4
  62. package/lib/esm/features/facets/VStringFacet.js.map +1 -1
  63. package/lib/esm/features/facets/VTypeFacet.js +4 -5
  64. package/lib/esm/features/facets/VTypeFacet.js.map +1 -1
  65. package/lib/esm/features/facets/VUserFacet.js +1 -1
  66. package/lib/esm/features/facets/VUserFacet.js.map +1 -1
  67. package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js +98 -0
  68. package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -0
  69. package/lib/esm/features/facets/index.js +3 -2
  70. package/lib/esm/features/facets/index.js.map +1 -1
  71. package/lib/esm/features/store/collections/CollectionsTable.js +1 -1
  72. package/lib/esm/features/store/collections/CollectionsTable.js.map +1 -1
  73. package/lib/esm/features/store/collections/CreateCollection.js +10 -9
  74. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
  75. package/lib/esm/features/store/collections/EditCollectionView.js +10 -9
  76. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  77. package/lib/esm/features/store/collections/SelectCollection.js +1 -1
  78. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
  79. package/lib/esm/features/store/objects/DocumentPreviewPanel.js +0 -1
  80. package/lib/esm/features/store/objects/DocumentPreviewPanel.js.map +1 -1
  81. package/lib/esm/features/store/objects/DocumentSearchResults.js +37 -2
  82. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  83. package/lib/esm/features/store/objects/components/ContentOverview.js +5 -6
  84. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  85. package/lib/esm/features/store/objects/components/SelectDocument.js +2 -2
  86. package/lib/esm/features/store/objects/components/SelectDocument.js.map +1 -1
  87. package/lib/esm/features/store/objects/components/VectorSearchWidget.js +1 -1
  88. package/lib/esm/features/store/objects/components/VectorSearchWidget.js.map +1 -1
  89. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +16 -4
  90. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  91. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +72 -37
  92. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  93. package/lib/esm/features/store/types/ObjectSchemaEditor.js +15 -0
  94. package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
  95. package/lib/esm/features/user/UserInfo.js +8 -8
  96. package/lib/esm/features/user/UserInfo.js.map +1 -1
  97. package/lib/esm/layout/FullHeightLayout.js +2 -4
  98. package/lib/esm/layout/FullHeightLayout.js.map +1 -1
  99. package/lib/esm/router/HistoryNavigator.js +2 -2
  100. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  101. package/lib/esm/shell/SplashScreen.js +19 -0
  102. package/lib/esm/shell/SplashScreen.js.map +1 -0
  103. package/lib/esm/shell/VertesiaShell.js +10 -0
  104. package/lib/esm/shell/VertesiaShell.js.map +1 -0
  105. package/lib/esm/shell/index.js +7 -0
  106. package/lib/esm/shell/index.js.map +1 -0
  107. package/lib/esm/shell/login/EnterpriseSigninButton.js +81 -0
  108. package/lib/esm/shell/login/EnterpriseSigninButton.js.map +1 -0
  109. package/lib/esm/shell/login/GitHubSignInButton.js +24 -0
  110. package/lib/esm/shell/login/GitHubSignInButton.js.map +1 -0
  111. package/lib/esm/shell/login/GoogleSignInButton.js +25 -0
  112. package/lib/esm/shell/login/GoogleSignInButton.js.map +1 -0
  113. package/lib/esm/shell/login/InviteAcceptModal.js +45 -0
  114. package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -0
  115. package/lib/esm/shell/login/MicrosoftSigninButton.js +19 -0
  116. package/lib/esm/shell/login/MicrosoftSigninButton.js.map +1 -0
  117. package/lib/esm/shell/login/PreviewIcon.js +23 -0
  118. package/lib/esm/shell/login/PreviewIcon.js.map +1 -0
  119. package/lib/esm/shell/login/SignInModal.js +9 -0
  120. package/lib/esm/shell/login/SignInModal.js.map +1 -0
  121. package/lib/esm/shell/login/SigninScreen.js +64 -0
  122. package/lib/esm/shell/login/SigninScreen.js.map +1 -0
  123. package/lib/esm/shell/login/SignupForm.js +91 -0
  124. package/lib/esm/shell/login/SignupForm.js.map +1 -0
  125. package/lib/esm/shell/login/TerminalLogin.js +179 -0
  126. package/lib/esm/shell/login/TerminalLogin.js.map +1 -0
  127. package/lib/esm/shell/login/UserInfo.js +40 -0
  128. package/lib/esm/shell/login/UserInfo.js.map +1 -0
  129. package/lib/esm/shell/login/UserSessionMenu.js +31 -0
  130. package/lib/esm/shell/login/UserSessionMenu.js.map +1 -0
  131. package/lib/esm/shell/utils.js +6 -0
  132. package/lib/esm/shell/utils.js.map +1 -0
  133. package/lib/esm/widgets/SvgIcon.js +36 -0
  134. package/lib/esm/widgets/SvgIcon.js.map +1 -0
  135. package/lib/esm/widgets/index.js +7 -6
  136. package/lib/esm/widgets/index.js.map +1 -1
  137. package/lib/esm/widgets/upload/UploadSummary.js +1 -1
  138. package/lib/esm/widgets/upload/UploadSummary.js.map +1 -1
  139. package/lib/tsconfig.tsbuildinfo +1 -1
  140. package/lib/types/core/components/FormItem.d.ts +2 -1
  141. package/lib/types/core/components/shadcn/dialog.d.ts +2 -1
  142. package/lib/types/core/components/shadcn/filters/DynamicLabel.d.ts +1 -1
  143. package/lib/types/core/components/shadcn/filters/comboBox/DateCombobox.d.ts +5 -0
  144. package/lib/types/core/components/shadcn/filters/comboBox/SelectCombobox.d.ts +8 -0
  145. package/lib/types/core/components/shadcn/filters/comboBox/StringListCombobox.d.ts +5 -0
  146. package/lib/types/core/components/shadcn/filters/comboBox/TextCombobox.d.ts +5 -0
  147. package/lib/types/core/components/shadcn/filters/comboBox/comboBox.d.ts +4 -0
  148. package/lib/types/core/components/shadcn/filters/{selectFilter.d.ts → filter/SelectFilter.d.ts} +2 -2
  149. package/lib/types/core/components/shadcn/filters/{stringListFilter.d.ts → filter/StringListFilter.d.ts} +1 -1
  150. package/lib/types/core/components/shadcn/filters/{textFilter.d.ts → filter/TextFilter.d.ts} +1 -1
  151. package/lib/types/core/components/shadcn/filters/{dateFilter.d.ts → filter/dateFilter.d.ts} +1 -1
  152. package/lib/types/core/components/shadcn/filters/filter-styles.d.ts +1 -0
  153. package/lib/types/core/components/shadcn/filters/filterBar.d.ts +14 -4
  154. package/lib/types/core/components/shadcn/filters/index.d.ts +1 -1
  155. package/lib/types/core/components/shadcn/filters/types.d.ts +2 -0
  156. package/lib/types/features/agent/PayloadBuilder.d.ts +17 -8
  157. package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts +2 -1
  158. package/lib/types/features/facets/DocumentsFacetsNav.d.ts +16 -0
  159. package/lib/types/features/facets/RunsFacetsNav.d.ts +18 -0
  160. package/lib/types/features/facets/VFacetsNav.d.ts +1 -1
  161. package/lib/types/features/facets/VStringFacet.d.ts +6 -2
  162. package/lib/types/features/facets/VTypeFacet.d.ts +3 -1
  163. package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts +13 -0
  164. package/lib/types/features/facets/index.d.ts +3 -2
  165. package/lib/types/shell/SplashScreen.d.ts +4 -0
  166. package/lib/types/shell/VertesiaShell.d.ts +7 -0
  167. package/lib/types/shell/index.d.ts +6 -0
  168. package/lib/types/shell/login/EnterpriseSigninButton.d.ts +5 -0
  169. package/lib/types/shell/login/GitHubSignInButton.d.ts +5 -0
  170. package/lib/types/shell/login/GoogleSignInButton.d.ts +5 -0
  171. package/lib/types/shell/login/InviteAcceptModal.d.ts +1 -0
  172. package/lib/types/shell/login/MicrosoftSigninButton.d.ts +5 -0
  173. package/lib/types/shell/login/PreviewIcon.d.ts +5 -0
  174. package/lib/types/shell/login/SignInModal.d.ts +6 -0
  175. package/lib/types/shell/login/SigninScreen.d.ts +8 -0
  176. package/lib/types/shell/login/SignupForm.d.ts +7 -0
  177. package/lib/types/shell/login/TerminalLogin.d.ts +1 -0
  178. package/lib/types/shell/login/UserInfo.d.ts +5 -0
  179. package/lib/types/shell/login/UserSessionMenu.d.ts +8 -0
  180. package/lib/types/shell/utils.d.ts +1 -0
  181. package/lib/types/widgets/SvgIcon.d.ts +6 -0
  182. package/lib/types/widgets/index.d.ts +7 -6
  183. package/lib/vertesia-ui-core.js +1 -1
  184. package/lib/vertesia-ui-core.js.map +1 -1
  185. package/lib/vertesia-ui-features.js +1 -1
  186. package/lib/vertesia-ui-features.js.map +1 -1
  187. package/lib/vertesia-ui-layout.js +1 -1
  188. package/lib/vertesia-ui-layout.js.map +1 -1
  189. package/lib/vertesia-ui-router.js +1 -1
  190. package/lib/vertesia-ui-router.js.map +1 -1
  191. package/lib/vertesia-ui-shell.js +2 -0
  192. package/lib/vertesia-ui-shell.js.map +1 -0
  193. package/lib/vertesia-ui-widgets.js +1 -1
  194. package/lib/vertesia-ui-widgets.js.map +1 -1
  195. package/package.json +14 -6
  196. package/src/core/components/Badge.tsx +12 -8
  197. package/src/core/components/FormItem.tsx +4 -3
  198. package/src/core/components/InputList.tsx +21 -17
  199. package/src/core/components/shadcn/checkbox.tsx +2 -2
  200. package/src/core/components/shadcn/command.tsx +1 -1
  201. package/src/core/components/shadcn/dialog.tsx +18 -9
  202. package/src/core/components/shadcn/filters/DynamicLabel.tsx +1 -2
  203. package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +211 -0
  204. package/src/core/components/shadcn/filters/{comboBox.tsx → comboBox/SelectCombobox.tsx} +8 -192
  205. package/src/core/components/shadcn/filters/comboBox/StringListCombobox.tsx +76 -0
  206. package/src/core/components/shadcn/filters/comboBox/TextCombobox.tsx +81 -0
  207. package/src/core/components/shadcn/filters/comboBox/comboBox.tsx +4 -0
  208. package/src/core/components/shadcn/filters/filter/SelectFilter.tsx +161 -0
  209. package/src/core/components/shadcn/filters/{stringListFilter.tsx → filter/StringListFilter.tsx} +7 -7
  210. package/src/core/components/shadcn/filters/{textFilter.tsx → filter/TextFilter.tsx} +17 -11
  211. package/src/core/components/shadcn/filters/filter/dateFilter.tsx +256 -0
  212. package/src/core/components/shadcn/filters/filter-styles.ts +87 -0
  213. package/src/core/components/shadcn/filters/filterBar.tsx +208 -152
  214. package/src/core/components/shadcn/filters/filters.tsx +7 -5
  215. package/src/core/components/shadcn/filters/index.ts +1 -1
  216. package/src/core/components/shadcn/filters/types.ts +2 -0
  217. package/src/core/components/toast/NotificationPanel.tsx +38 -22
  218. package/src/features/agent/PayloadBuilder.tsx +56 -31
  219. package/src/features/agent/chat/ModernAgentConversation.tsx +645 -639
  220. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +7 -6
  221. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +13 -2
  222. package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +2 -1
  223. package/src/features/agent/chat/ModernAgentOutput/utils.ts +12 -4
  224. package/src/features/facets/DocumentsFacetsNav.tsx +171 -0
  225. package/src/features/facets/RunsFacetsNav.tsx +166 -0
  226. package/src/features/facets/VFacetsNav.tsx +10 -126
  227. package/src/features/facets/VStringFacet.tsx +10 -4
  228. package/src/features/facets/VTypeFacet.tsx +6 -5
  229. package/src/features/facets/VUserFacet.tsx +5 -3
  230. package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +132 -0
  231. package/src/features/facets/index.ts +5 -2
  232. package/src/features/store/collections/CollectionsTable.tsx +3 -2
  233. package/src/features/store/collections/CreateCollection.tsx +17 -15
  234. package/src/features/store/collections/EditCollectionView.tsx +19 -16
  235. package/src/features/store/collections/SelectCollection.tsx +1 -1
  236. package/src/features/store/objects/DocumentPreviewPanel.tsx +0 -1
  237. package/src/features/store/objects/DocumentSearchResults.tsx +80 -11
  238. package/src/features/store/objects/components/ContentOverview.tsx +7 -7
  239. package/src/features/store/objects/components/SelectDocument.tsx +2 -2
  240. package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
  241. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +40 -19
  242. package/src/features/store/objects/upload/DocumentUploadModal.tsx +160 -214
  243. package/src/features/store/types/ObjectSchemaEditor.tsx +15 -0
  244. package/src/features/user/UserInfo.tsx +17 -14
  245. package/src/layout/FullHeightLayout.tsx +2 -2
  246. package/src/router/HistoryNavigator.ts +2 -2
  247. package/src/shell/SplashScreen.tsx +41 -0
  248. package/src/shell/VertesiaShell.tsx +27 -0
  249. package/src/shell/index.tsx +6 -0
  250. package/src/shell/login/EnterpriseSigninButton.tsx +106 -0
  251. package/src/shell/login/GitHubSignInButton.tsx +40 -0
  252. package/src/shell/login/GoogleSignInButton.tsx +36 -0
  253. package/src/shell/login/InviteAcceptModal.tsx +78 -0
  254. package/src/shell/login/MicrosoftSigninButton.tsx +30 -0
  255. package/src/shell/login/PreviewIcon.tsx +29 -0
  256. package/src/shell/login/SignInModal.tsx +28 -0
  257. package/src/shell/login/SigninScreen.tsx +162 -0
  258. package/src/shell/login/SignupForm.tsx +178 -0
  259. package/src/shell/login/TerminalLogin.tsx +299 -0
  260. package/src/shell/login/UserInfo.tsx +76 -0
  261. package/src/shell/login/UserSessionMenu.tsx +81 -0
  262. package/src/shell/utils.tsx +7 -0
  263. package/src/widgets/SvgIcon.tsx +44 -0
  264. package/src/widgets/index.ts +7 -6
  265. package/src/widgets/upload/UploadSummary.tsx +3 -4
  266. package/lib/esm/core/components/shadcn/filters/comboBox.js +0 -101
  267. package/lib/esm/core/components/shadcn/filters/comboBox.js.map +0 -1
  268. package/lib/esm/core/components/shadcn/filters/dateFilter.js +0 -36
  269. package/lib/esm/core/components/shadcn/filters/dateFilter.js.map +0 -1
  270. package/lib/esm/core/components/shadcn/filters/selectFilter.js +0 -67
  271. package/lib/esm/core/components/shadcn/filters/selectFilter.js.map +0 -1
  272. package/lib/esm/core/components/shadcn/filters/stringListFilter.js.map +0 -1
  273. package/lib/esm/core/components/shadcn/filters/textFilter.js.map +0 -1
  274. package/lib/esm/features/facets/InteractionFacet.js +0 -39
  275. package/lib/esm/features/facets/InteractionFacet.js.map +0 -1
  276. package/lib/esm/features/facets/TypeOptions.js +0 -19
  277. package/lib/esm/features/facets/TypeOptions.js.map +0 -1
  278. package/lib/esm/features/facets/UserFacet.js +0 -33
  279. package/lib/esm/features/facets/UserFacet.js.map +0 -1
  280. package/lib/types/core/components/shadcn/filters/comboBox.d.ts +0 -22
  281. package/lib/types/features/facets/InteractionFacet.d.ts +0 -9
  282. package/lib/types/features/facets/TypeOptions.d.ts +0 -3
  283. package/lib/types/features/facets/UserFacet.d.ts +0 -11
  284. package/src/core/components/shadcn/filters/dateFilter.tsx +0 -82
  285. package/src/core/components/shadcn/filters/selectFilter.tsx +0 -110
  286. package/src/features/facets/InteractionFacet.tsx +0 -53
  287. package/src/features/facets/TypeOptions.tsx +0 -22
  288. package/src/features/facets/UserFacet.tsx +0 -61
@@ -0,0 +1,162 @@
1
+ import { SignupData, SignupPayload } from "@vertesia/common";
2
+ import { Button, useSafeLayoutEffect } from "@vertesia/ui/core";
3
+ import { Env } from "@vertesia/ui/env";
4
+ import { UserNotFoundError, useUserSession, useUXTracking } from "@vertesia/ui/session";
5
+ import clsx from "clsx";
6
+ import { useEffect, useState } from "react";
7
+ import EnterpriseSigninButton from "./EnterpriseSigninButton";
8
+ import GitHubSignInButton from "./GitHubSignInButton";
9
+ import GoogleSignInButton from "./GoogleSignInButton";
10
+ import MicrosoftSignInButton from "./MicrosoftSigninButton";
11
+ import SignupForm from "./SignupForm";
12
+
13
+ interface SigninScreenProps {
14
+ isNested?: boolean;
15
+ allowedPrefix?: string;
16
+ lightLogo?: string;
17
+ darkLogo?: string;
18
+ }
19
+ export function SigninScreen({ allowedPrefix, isNested = false, lightLogo, darkLogo }: SigninScreenProps) {
20
+ const [allow, setAllow] = useState(false);
21
+ useSafeLayoutEffect(() => {
22
+ allowedPrefix && setAllow(window.location.href.startsWith(allowedPrefix));
23
+ }, []);
24
+ return allow ? null : <SigninScreenImpl isNested={isNested} lightLogo={lightLogo} darkLogo={darkLogo} />;
25
+ }
26
+
27
+ function SigninScreenImpl({ isNested = false, lightLogo, darkLogo }: SigninScreenProps) {
28
+ const { isLoading, user, authError } = useUserSession();
29
+
30
+ return !isLoading && !user ? (
31
+ <div
32
+ style={{ zIndex: 999998 }}
33
+ className={(isNested ? "absolute" : "fixed") + "overflow-y-auto "}
34
+ >
35
+ <div
36
+ className={clsx(
37
+ "flex flex-col items-center justify-center py-14 px-4",
38
+ )}
39
+ >
40
+
41
+ <StandardSigninPanel authError={authError} lightLogo={lightLogo} darkLogo={darkLogo} />
42
+ <div className="flex gap-x-6 mt-10 justify-center text-muted">
43
+ <a href="https://vertesiahq.com/privacy" className="text-sm">
44
+ Privacy Policy
45
+ </a>
46
+ <a href="https://vertesiahq.com/terms" className="text-sm">
47
+ Terms of Service
48
+ </a>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ ) : null;
53
+ }
54
+
55
+ function StandardSigninPanel({ authError, darkLogo, lightLogo }: {
56
+ authError?: Error,
57
+ darkLogo?: string,
58
+ lightLogo?: string
59
+ }) {
60
+ const [signupData, setSignupData] = useState<SignupData | undefined>(undefined);
61
+ const [collectSignupData, setCollectSignupData] = useState(false);
62
+ const { signOut } = useUserSession();
63
+ const { trackEvent } = useUXTracking();
64
+
65
+ history.replaceState({}, '', '/');
66
+
67
+ const goBack = () => {
68
+ console.log("Going back, signing out");
69
+ setSignupData(undefined);
70
+ setCollectSignupData(false);
71
+ signOut();
72
+ };
73
+
74
+ const goToSignup = () => {
75
+ setSignupData(undefined);
76
+ setCollectSignupData(true);
77
+ };
78
+
79
+ useEffect(() => {
80
+ if (authError instanceof UserNotFoundError) {
81
+ console.log("User not found, redirecting to signup");
82
+ goToSignup();
83
+ }
84
+ }, [authError]);
85
+
86
+ const onSignup = (data: SignupData, fbToken: string) => {
87
+ console.log("Got Signup data", data);
88
+ setSignupData(data);
89
+ const payload: SignupPayload = {
90
+ signupData: data,
91
+ firebaseToken: fbToken,
92
+ };
93
+ fetch(Env.endpoints.studio + "/auth/signup", {
94
+ method: "POST",
95
+ headers: { "Content-Type": "application/json" },
96
+ body: JSON.stringify(payload),
97
+ }).then((res) => {
98
+ console.log("Signup successful", payload, res);
99
+
100
+ trackEvent("sign_up");
101
+ window.location.href = "/";
102
+ });
103
+ };
104
+
105
+ return (
106
+ <>
107
+ {lightLogo && <img src={lightLogo} alt='logo' className='h-15 block dark:hidden' />}
108
+ {darkLogo && <img src={darkLogo} alt='logo' className='h-15 hidden dark:block' />}
109
+
110
+ {signupData && (
111
+ <div className="my-6">
112
+ Need to make a change?{" "}
113
+ <Button onClick={goToSignup}> Go back</Button>
114
+ </div>
115
+ )}
116
+ <div className="flex flex-col space-y-2">
117
+ {collectSignupData && !localStorage.getItem('tenantName') ? (
118
+ <SignupForm onSignup={onSignup} goBack={goBack} />
119
+ ) : (
120
+
121
+ <div className="flex flex-col">
122
+ <div className="my-4">
123
+ <h2 className="text-2xl font-bold text-center">Log in or Sign up</h2>
124
+ </div>
125
+ <div className="max-w-2xl text-center my-2 px-2">
126
+ First time here? No problem, it&apos;s free to try!
127
+ <br />
128
+ We&apos;ll just ask you a couple of questions next and you&apos;ll be on your way.
129
+ </div>
130
+ <div className="flex items-center flex-col">
131
+ <div className="py-4 w-70">
132
+ <GoogleSignInButton />
133
+ <GitHubSignInButton />
134
+ <MicrosoftSignInButton />
135
+ </div>
136
+ <div className="flex items-center flex-row w-70 text-muted">
137
+ <hr className="w-full" />
138
+ <div className="px-2 text-xs">OR</div>
139
+ <hr className="w-full" />
140
+ </div>
141
+ <div className="py-4 w-70">
142
+ <EnterpriseSigninButton />
143
+ </div>
144
+ </div>
145
+ {authError && (
146
+ <div className="text-center">
147
+ <div className="">
148
+ Sorry, we have not been able to sign you in.
149
+ <br />
150
+ Please try again or contact
151
+ <a className='text-info mx-1' href="mailto:support@vertesiahq.com">support@vertesiahq.com</a>
152
+ if it persists.
153
+ <pre className="mt-2">Error: {authError.message}</pre>
154
+ </div>
155
+ </div>
156
+ )}
157
+ </div>
158
+ )}
159
+ </div>
160
+ </>
161
+ );
162
+ }
@@ -0,0 +1,178 @@
1
+ import { SignupData } from "@vertesia/common";
2
+ import { Button, Input, VSelectBox, SelectStack } from "@vertesia/ui/core";
3
+ import { User, getAuth } from "firebase/auth";
4
+ import { useEffect, useState } from "react";
5
+
6
+
7
+ interface CompanySizeOption {
8
+ id: number;
9
+ label: string;
10
+ }
11
+
12
+ const companySizeOptions: CompanySizeOption[] = [
13
+ { id: 1, label: "1-10 employees" },
14
+ { id: 11, label: "11-100 employees" },
15
+ { id: 101, label: "101-1000 employees" },
16
+ { id: 1001, label: "1001-5000 employees" },
17
+ { id: 5001, label: "5000+ employees" },
18
+ ];
19
+
20
+ const accountTypeOptions = [
21
+ {
22
+ id: "personal",
23
+ label: "Personal",
24
+ description: "For personal use, or for a small team.",
25
+ },
26
+ {
27
+ id: "company",
28
+ label: "Company",
29
+ description: "For a company or organization.",
30
+ },
31
+ ];
32
+
33
+ const projectMaturityOptions = [
34
+ { id: "testing", label: "Just Testing or Evaluating LLMs" },
35
+ { id: "exploring", label: "Actively Exploring LLMs on a Project" },
36
+ { id: "using", label: "Already Using LLMs in Production" },
37
+ { id: "migrating", label: "Migrating to different LLMs" },
38
+ { id: "other", label: "Other" },
39
+ ];
40
+
41
+ interface SignupFormProps {
42
+ onSignup: (data: SignupData, fbToken: string) => void;
43
+ goBack: () => void;
44
+ }
45
+
46
+ export default function SignupForm({ onSignup, goBack }: SignupFormProps) {
47
+ const [accountType, setAccountType] = useState<string | undefined>(undefined);
48
+ const [companySize, setCompanySize] = useState<CompanySizeOption | undefined>(undefined);
49
+ const [companyName, setCompanyName] = useState<string | undefined>(undefined);
50
+ const [companyWebsite, setCompanyWebsite] = useState<string | undefined>(undefined);
51
+ const [projectMaturity, setProjectMaturity] = useState<string | undefined>(undefined);
52
+ const [fbUser, setFbUser] = useState<User | undefined>(undefined);
53
+
54
+ const [error, setError] = useState<string | undefined>(undefined);
55
+ const isCompany = accountType === "company";
56
+
57
+ useEffect(() => {
58
+ const user = getAuth().currentUser;
59
+ if (!user) {
60
+ console.error('No user found');
61
+ return;
62
+ }
63
+ setFbUser(user);
64
+ }, [fbUser]);
65
+
66
+ const isValid = () => {
67
+ if (!accountType) {
68
+ setError("Please select an account type");
69
+ return false;
70
+ }
71
+ if (isCompany && !companyName) {
72
+ setError("Please enter an organization name");
73
+ return false;
74
+ }
75
+
76
+ if (isCompany && !companySize) {
77
+ setError("Please select a company size");
78
+ return false;
79
+ }
80
+
81
+ return true
82
+ }
83
+
84
+
85
+ const onSubmit = async () => {
86
+ if (!isValid()) return;
87
+ if (!accountType) return;
88
+
89
+ const signupData = {
90
+ accountType: accountType,
91
+ companyName: companyName,
92
+ companySize: companySize?.id,
93
+ companyWebsite: companyWebsite,
94
+ maturity: projectMaturity,
95
+ };
96
+
97
+ window.localStorage.setItem("composableSignupData", JSON.stringify(signupData));
98
+
99
+ const fbToken = await getAuth().currentUser?.getIdToken();
100
+ console.log('Got firebase token', getAuth(), fbToken);
101
+ if (!fbToken) {
102
+ console.error('No firebase token found');
103
+ return;
104
+ }
105
+
106
+ onSignup(signupData, fbToken);
107
+
108
+ }
109
+
110
+ return (
111
+ <div className="flex flex-col space-y-2">
112
+ <div className="prose">
113
+ <p className="prose text-sm text-muted pt-4">
114
+ Welcome to Vertesia, {fbUser?.displayName} ({fbUser?.email}).
115
+ Please tell us a little bit about yourself and you&apos;ll be on your way.
116
+ No credit card is required.
117
+ </p>
118
+ {error &&
119
+ <div className="text-destructive">{error}</div>
120
+ }
121
+ </div>
122
+ <FormItem label="Account Type">
123
+ <SelectStack
124
+ options={accountTypeOptions}
125
+ selected={accountTypeOptions.find((option) => option.id === accountType)}
126
+ onSelect={(option) => setAccountType(option.id)}
127
+ />
128
+ </FormItem>
129
+ {isCompany &&
130
+ <>
131
+ <FormItem label="Company Size">
132
+ <VSelectBox className="w-full border border-accent bg-muted"
133
+ value={companySize}
134
+ options={companySizeOptions}
135
+ onChange={setCompanySize}
136
+ optionLabel={(option) => option?.label}
137
+ placeholder='Select Company Size'
138
+ />
139
+ </FormItem>
140
+ <FormItem label="Company Name">
141
+ <Input value={companyName} onChange={setCompanyName} type="text" required={true} />
142
+ </FormItem>
143
+ <FormItem label="Company Website">
144
+ <Input value={companyWebsite} onChange={setCompanyWebsite} type="text" />
145
+ </FormItem>
146
+ </>
147
+ }
148
+ <FormItem label="Project Maturity">
149
+ <VSelectBox className="w-full border border-accent bg-muted"
150
+ options={projectMaturityOptions}
151
+ value={projectMaturityOptions.find((option) => option.id === projectMaturity)}
152
+ optionLabel={(option) => option?.label}
153
+ placeholder='Select Project Maturity'
154
+ onChange={(option) => setProjectMaturity(option?.id)}
155
+ />
156
+ </FormItem>
157
+ <div className="pt-8 flex flex-col">
158
+ <Button variant="primary" onClick={onSubmit} size="xl">
159
+ <span className="text-lg">Sign Up</span>
160
+ </Button>
161
+ <Button variant="ghost" size="xl" className="mt-4" onClick={goBack}>
162
+ <span className="">Wrong account, go back</span>
163
+ </Button>
164
+ </div>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ function FormItem({ label, children }: { label: string, children: React.ReactNode }) {
170
+
171
+ return (
172
+ <div className="flex flex-col space-y-2 pt-4">
173
+ <div className="text-sm text-muted">{label}</div>
174
+ {children}
175
+ </div>
176
+ )
177
+
178
+ }
@@ -0,0 +1,299 @@
1
+ import { useState } from 'react'
2
+
3
+ import { AccountRef, ProjectRef } from '@vertesia/common'
4
+ import { Button, Center, ErrorBox, Input, SelectBox, Spinner, useFetch, useToast } from '@vertesia/ui/core'
5
+ import { Env } from "@vertesia/ui/env"
6
+ import { useLocation } from "@vertesia/ui/router"
7
+ import { fetchComposableTokenFromFirebaseToken, useUserSession } from '@vertesia/ui/session'
8
+
9
+ interface ProfileData {
10
+ profile?: string
11
+ account?: string
12
+ project?: string
13
+ }
14
+
15
+ interface LoginResult extends Required<ProfileData> {
16
+ token: string
17
+ studio_server_url: string
18
+ zeno_server_url: string
19
+ }
20
+
21
+ interface ClientInfo extends ProfileData {
22
+ redirect: string
23
+ code: string
24
+ }
25
+
26
+ function getClientInfo(location: Location): ClientInfo | null {
27
+ const params = new URLSearchParams(location.search)
28
+ let redirect = params.get('redirect_uri')
29
+ const code = params.get('code')
30
+ if (!redirect || !code) {
31
+ return null
32
+ }
33
+ redirect = decodeURI(redirect)
34
+ if (!redirect.startsWith('http://127.0.0.1:') && !redirect.startsWith('http://localhost:')) {
35
+ return null
36
+ }
37
+ const profile = params.get('profile') ?? "default"
38
+ const project = params.get('project') ?? undefined
39
+ const account = params.get('account') ?? undefined
40
+ return { redirect, code, profile, project, account }
41
+ }
42
+
43
+ export function TerminalLogin() {
44
+ const [payload, setPayload] = useState<LoginResult | undefined>()
45
+ const [error, setError] = useState<Error>()
46
+ const location = useLocation()
47
+ const clientInfo = getClientInfo(location)
48
+ const toast = useToast()
49
+
50
+ const onAccept = async (data: ProfileData) => {
51
+ if (!clientInfo) return
52
+ if (!data.profile) {
53
+ toast({
54
+ title: 'Profile is required',
55
+ description: 'Please enter a profile name to save the client authorization',
56
+ status: 'error',
57
+ duration: 2000
58
+ })
59
+ return
60
+ }
61
+ if (!data.account) {
62
+ toast({
63
+ title: 'Account is required',
64
+ description: 'Please select an account to authorize the client to access the ComposablePrompts servers',
65
+ status: 'error',
66
+ duration: 2000
67
+ })
68
+ return
69
+ }
70
+ if (!data.project) {
71
+ toast({
72
+ title: 'Project is required',
73
+ description: 'Please select a project to authorize the client to access the ComposablePrompts servers',
74
+ status: 'error',
75
+ duration: 2000
76
+ })
77
+ return
78
+ }
79
+
80
+ // expire in 1 day
81
+ let payload: LoginResult | undefined
82
+ try {
83
+ const token = await fetchComposableTokenFromFirebaseToken(data.account, data.project, 24 * 3600)
84
+ if (token) {
85
+ payload = {
86
+ ...data,
87
+ studio_server_url: Env.endpoints.studio,
88
+ zeno_server_url: Env.endpoints.zeno,
89
+ token,
90
+ } as LoginResult
91
+ await fetch(clientInfo.redirect, {
92
+ method: 'POST',
93
+ headers: {
94
+ 'Content-Type': 'application/json'
95
+ },
96
+ body: JSON.stringify(payload)
97
+ })
98
+ setPayload(payload)
99
+ } else {
100
+ toast({
101
+ title: 'Failed to get composable token',
102
+ status: 'error',
103
+ duration: 5000
104
+ })
105
+ }
106
+ } catch (err: any) {
107
+ if (payload) {
108
+ setError(err)
109
+ setPayload(payload)
110
+ } else {
111
+ toast({
112
+ title: 'Error authorizing client',
113
+ description: err.message,
114
+ status: 'error',
115
+ duration: 5000
116
+ })
117
+ }
118
+ }
119
+ }
120
+
121
+ const getPageContent = () => {
122
+ if (!clientInfo) {
123
+ return <ErrorBox title='Invalid request'>This page should be called by a terminal client to authenticate against the ComposablePrompts servers</ErrorBox>
124
+ }
125
+
126
+ return payload
127
+ ? <AuthDoneScreen payload={payload} error={error} />
128
+ : <AuthAcceptScreen clientInfo={clientInfo} onAccept={onAccept} />
129
+ }
130
+
131
+ const page = getPageContent()
132
+
133
+ return (
134
+ <div className="w-full flex flex-col items-center gap-4 mt-24">{page}</div>
135
+ )
136
+ }
137
+
138
+ interface AuthAcceptScreenProps {
139
+ onAccept: (data: ProfileData) => void
140
+ clientInfo: ClientInfo
141
+ }
142
+ function AuthAcceptScreen({ onAccept, clientInfo }: Readonly<AuthAcceptScreenProps>) {
143
+ const { client, user } = useUserSession()
144
+ const { data: allProjects, error } = useFetch(() => user ? client.projects.list() : Promise.resolve([]), [user])
145
+
146
+
147
+ if (error) {
148
+ return <ErrorBox title='Error loading projects'>{error.message}</ErrorBox>
149
+ }
150
+
151
+ const getEnvironmentName = () => {
152
+ if (Env.isLocalDev) {
153
+ return "Local Dev"
154
+ } else if (Env.isDev) {
155
+ return "Staging"
156
+ }
157
+ return "Production"
158
+ }
159
+
160
+ const envName = getEnvironmentName()
161
+
162
+ return user && allProjects ? (
163
+ <>
164
+ <div className='w-1/3'>
165
+ <div className="mb-4 text-xl font-semibold text-gray-800">
166
+ Authorizing client on {envName} environment.
167
+ </div>
168
+ <div className='mb-2 text-md text-gray-800'>
169
+ <div>A client app wants authorization to access the composable prompt servers in your name.</div>
170
+ <div>The client app code is <b>{clientInfo.code}</b>. You can check if the code is correct in the terminal.</div>
171
+ </div>
172
+ <div className='mb-2 text-sm text-gray-600'>
173
+ <div>You must choose the target account and project for the client to access.</div>
174
+ <div>Also, enter a profile name that will be used to save the authorization in your client configuration.</div>
175
+ </div>
176
+ </div>
177
+ <ProfileForm onAccept={onAccept} allProjects={allProjects} data={clientInfo} />
178
+ </>
179
+ ) : <Spinner size='lg' />
180
+ }
181
+
182
+ function AuthDoneScreen({ payload, error }: Readonly<{ payload: LoginResult, error?: Error }>) {
183
+ const toast = useToast()
184
+ const onCopy = () => {
185
+ if (payload) {
186
+ navigator.clipboard.writeText(JSON.stringify(payload))
187
+ toast({
188
+ title: 'Authentication Payload copied',
189
+ description: error ? 'You can paste the authentication payload in the terminal to authenticate the client.' : 'You can close the page now.',
190
+ status: 'success',
191
+ duration: 5000
192
+ })
193
+ }
194
+ }
195
+
196
+ return (
197
+ <div>
198
+ {
199
+ error ?
200
+ <div>
201
+ <ErrorBox title='Failed to send the authorization token to the cli tool'>This can happen due to security checks on Safari. The error is &quot;{error.message}&quot;</ErrorBox>
202
+ <div>Don&apos;t worry, you can still authenticate the cli tool by pasting the authentication token in the terminal.
203
+ You can close this page.</div>
204
+ </div>
205
+ : <div>The client is authenticated. You can close this page.</div>
206
+ }
207
+ <Center className="mt-4">
208
+ <Button variant='secondary' onClick={onCopy}>Copy the Authentication Payload</Button>
209
+ </Center>
210
+ </div>
211
+ )
212
+ }
213
+
214
+ interface ProfileFormProps {
215
+ onAccept: (data: ProfileData) => void
216
+ allProjects: ProjectRef[]
217
+ data: ProfileData
218
+ }
219
+ function ProfileForm({ allProjects, data, onAccept }: Readonly<ProfileFormProps>) {
220
+ const { accounts, account, project } = useUserSession()
221
+ const [currentData, setCurrentData] = useState<ProfileData>(() => ({
222
+ profile: data.profile,
223
+ account: data.account ?? account?.id,
224
+ project: data.project ?? project?.id,
225
+ }))
226
+
227
+ const onChangeProfile = (value: string) => {
228
+ setCurrentData({ ...currentData, profile: value })
229
+ }
230
+
231
+ const onChangeAccount = (value: AccountRef) => {
232
+ setCurrentData({ ...currentData, account: value.id, project: undefined })
233
+ }
234
+
235
+ const onChangeProject = (value: ProjectRef) => {
236
+ setCurrentData({ ...currentData, project: value.id })
237
+ }
238
+
239
+ const projects = allProjects.filter(p => p.account === currentData.account)
240
+
241
+ return (
242
+ <div className='w-1/3'>
243
+ <div className="mb-4 flex flex-col gap-2">
244
+ <span className="font-semibold text-gray-600">Profile Name</span>
245
+ <Input type='text' value={currentData.profile} onChange={onChangeProfile} />
246
+ </div>
247
+ <div className="mb-4 flex flex-col gap-2">
248
+ <span className="font-semibold text-gray-600">Account</span>
249
+ <SelectAccount value={currentData.account} onChange={onChangeAccount} accounts={accounts || []} />
250
+ </div>
251
+ <div className="mb-4 flex flex-col gap-2">
252
+ <span className="font-semibold text-gray-600">Project</span>
253
+ <SelectProject value={currentData.project} onChange={onChangeProject} projects={projects} />
254
+ </div>
255
+ <div className="pt-2">
256
+ <Button size='xl' onClick={() => onAccept(currentData)}>Authorize Client</Button>
257
+ </div>
258
+ </div>
259
+ )
260
+ }
261
+
262
+ interface SelectAccountProps {
263
+ value?: string
264
+ accounts: AccountRef[]
265
+ onChange: (value: AccountRef) => void
266
+ }
267
+ function SelectAccount({ value, accounts, onChange }: Readonly<SelectAccountProps>) {
268
+ const _onChange = (value: AccountRef) => {
269
+ onChange(value)
270
+ }
271
+ return <SelectBox
272
+ options={accounts}
273
+ value={accounts?.find(a => a.id === value)}
274
+ onChange={_onChange}
275
+ by="id"
276
+ optionLabel={(option) => option.name}
277
+ placeholder='Select Account'
278
+ />
279
+ }
280
+
281
+ interface SelectProjectProps {
282
+ value?: string
283
+ projects: ProjectRef[]
284
+ onChange: (value: ProjectRef) => void
285
+ }
286
+ function SelectProject({ value, projects, onChange }: Readonly<SelectProjectProps>) {
287
+ const _onChange = (value: ProjectRef) => {
288
+ onChange(value)
289
+ }
290
+ return (
291
+ <SelectBox
292
+ by="id"
293
+ value={projects.find(p => p.id === value)}
294
+ options={projects}
295
+ optionLabel={(option) => option.name}
296
+ placeholder='Select Project'
297
+ onChange={_onChange} />
298
+ )
299
+ }