@vertesia/ui 0.67.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 (283) 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 +9 -3
  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 +12 -1
  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 +0 -2
  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/router/HistoryNavigator.js +2 -2
  98. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  99. package/lib/esm/shell/SplashScreen.js +19 -0
  100. package/lib/esm/shell/SplashScreen.js.map +1 -0
  101. package/lib/esm/shell/VertesiaShell.js +10 -0
  102. package/lib/esm/shell/VertesiaShell.js.map +1 -0
  103. package/lib/esm/shell/index.js +7 -0
  104. package/lib/esm/shell/index.js.map +1 -0
  105. package/lib/esm/shell/login/EnterpriseSigninButton.js +81 -0
  106. package/lib/esm/shell/login/EnterpriseSigninButton.js.map +1 -0
  107. package/lib/esm/shell/login/GitHubSignInButton.js +24 -0
  108. package/lib/esm/shell/login/GitHubSignInButton.js.map +1 -0
  109. package/lib/esm/shell/login/GoogleSignInButton.js +25 -0
  110. package/lib/esm/shell/login/GoogleSignInButton.js.map +1 -0
  111. package/lib/esm/shell/login/InviteAcceptModal.js +45 -0
  112. package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -0
  113. package/lib/esm/shell/login/MicrosoftSigninButton.js +19 -0
  114. package/lib/esm/shell/login/MicrosoftSigninButton.js.map +1 -0
  115. package/lib/esm/shell/login/PreviewIcon.js +23 -0
  116. package/lib/esm/shell/login/PreviewIcon.js.map +1 -0
  117. package/lib/esm/shell/login/SignInModal.js +9 -0
  118. package/lib/esm/shell/login/SignInModal.js.map +1 -0
  119. package/lib/esm/shell/login/SigninScreen.js +64 -0
  120. package/lib/esm/shell/login/SigninScreen.js.map +1 -0
  121. package/lib/esm/shell/login/SignupForm.js +91 -0
  122. package/lib/esm/shell/login/SignupForm.js.map +1 -0
  123. package/lib/esm/shell/login/TerminalLogin.js +179 -0
  124. package/lib/esm/shell/login/TerminalLogin.js.map +1 -0
  125. package/lib/esm/shell/login/UserInfo.js +40 -0
  126. package/lib/esm/shell/login/UserInfo.js.map +1 -0
  127. package/lib/esm/shell/login/UserSessionMenu.js +31 -0
  128. package/lib/esm/shell/login/UserSessionMenu.js.map +1 -0
  129. package/lib/esm/shell/utils.js +6 -0
  130. package/lib/esm/shell/utils.js.map +1 -0
  131. package/lib/esm/widgets/SvgIcon.js +36 -0
  132. package/lib/esm/widgets/SvgIcon.js.map +1 -0
  133. package/lib/esm/widgets/index.js +7 -6
  134. package/lib/esm/widgets/index.js.map +1 -1
  135. package/lib/esm/widgets/upload/UploadSummary.js +1 -1
  136. package/lib/esm/widgets/upload/UploadSummary.js.map +1 -1
  137. package/lib/tsconfig.tsbuildinfo +1 -1
  138. package/lib/types/core/components/FormItem.d.ts +2 -1
  139. package/lib/types/core/components/shadcn/dialog.d.ts +2 -1
  140. package/lib/types/core/components/shadcn/filters/DynamicLabel.d.ts +1 -1
  141. package/lib/types/core/components/shadcn/filters/comboBox/DateCombobox.d.ts +5 -0
  142. package/lib/types/core/components/shadcn/filters/comboBox/SelectCombobox.d.ts +8 -0
  143. package/lib/types/core/components/shadcn/filters/comboBox/StringListCombobox.d.ts +5 -0
  144. package/lib/types/core/components/shadcn/filters/comboBox/TextCombobox.d.ts +5 -0
  145. package/lib/types/core/components/shadcn/filters/comboBox/comboBox.d.ts +4 -0
  146. package/lib/types/core/components/shadcn/filters/{selectFilter.d.ts → filter/SelectFilter.d.ts} +2 -2
  147. package/lib/types/core/components/shadcn/filters/{stringListFilter.d.ts → filter/StringListFilter.d.ts} +1 -1
  148. package/lib/types/core/components/shadcn/filters/{textFilter.d.ts → filter/TextFilter.d.ts} +1 -1
  149. package/lib/types/core/components/shadcn/filters/{dateFilter.d.ts → filter/dateFilter.d.ts} +1 -1
  150. package/lib/types/core/components/shadcn/filters/filter-styles.d.ts +1 -0
  151. package/lib/types/core/components/shadcn/filters/filterBar.d.ts +14 -4
  152. package/lib/types/core/components/shadcn/filters/index.d.ts +1 -1
  153. package/lib/types/core/components/shadcn/filters/types.d.ts +2 -0
  154. package/lib/types/features/agent/PayloadBuilder.d.ts +17 -8
  155. package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts +2 -1
  156. package/lib/types/features/facets/DocumentsFacetsNav.d.ts +16 -0
  157. package/lib/types/features/facets/RunsFacetsNav.d.ts +18 -0
  158. package/lib/types/features/facets/VFacetsNav.d.ts +1 -1
  159. package/lib/types/features/facets/VStringFacet.d.ts +6 -2
  160. package/lib/types/features/facets/VTypeFacet.d.ts +3 -1
  161. package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts +13 -0
  162. package/lib/types/features/facets/index.d.ts +3 -2
  163. package/lib/types/shell/SplashScreen.d.ts +4 -0
  164. package/lib/types/shell/VertesiaShell.d.ts +7 -0
  165. package/lib/types/shell/index.d.ts +6 -0
  166. package/lib/types/shell/login/EnterpriseSigninButton.d.ts +5 -0
  167. package/lib/types/shell/login/GitHubSignInButton.d.ts +5 -0
  168. package/lib/types/shell/login/GoogleSignInButton.d.ts +5 -0
  169. package/lib/types/shell/login/InviteAcceptModal.d.ts +1 -0
  170. package/lib/types/shell/login/MicrosoftSigninButton.d.ts +5 -0
  171. package/lib/types/shell/login/PreviewIcon.d.ts +5 -0
  172. package/lib/types/shell/login/SignInModal.d.ts +6 -0
  173. package/lib/types/shell/login/SigninScreen.d.ts +8 -0
  174. package/lib/types/shell/login/SignupForm.d.ts +7 -0
  175. package/lib/types/shell/login/TerminalLogin.d.ts +1 -0
  176. package/lib/types/shell/login/UserInfo.d.ts +5 -0
  177. package/lib/types/shell/login/UserSessionMenu.d.ts +8 -0
  178. package/lib/types/shell/utils.d.ts +1 -0
  179. package/lib/types/widgets/SvgIcon.d.ts +6 -0
  180. package/lib/types/widgets/index.d.ts +7 -6
  181. package/lib/vertesia-ui-core.js +1 -1
  182. package/lib/vertesia-ui-core.js.map +1 -1
  183. package/lib/vertesia-ui-features.js +1 -1
  184. package/lib/vertesia-ui-features.js.map +1 -1
  185. package/lib/vertesia-ui-router.js +1 -1
  186. package/lib/vertesia-ui-router.js.map +1 -1
  187. package/lib/vertesia-ui-shell.js +2 -0
  188. package/lib/vertesia-ui-shell.js.map +1 -0
  189. package/lib/vertesia-ui-widgets.js +1 -1
  190. package/lib/vertesia-ui-widgets.js.map +1 -1
  191. package/package.json +14 -6
  192. package/src/core/components/Badge.tsx +12 -8
  193. package/src/core/components/FormItem.tsx +4 -3
  194. package/src/core/components/InputList.tsx +21 -17
  195. package/src/core/components/shadcn/checkbox.tsx +2 -2
  196. package/src/core/components/shadcn/command.tsx +1 -1
  197. package/src/core/components/shadcn/dialog.tsx +18 -9
  198. package/src/core/components/shadcn/filters/DynamicLabel.tsx +1 -2
  199. package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +211 -0
  200. package/src/core/components/shadcn/filters/{comboBox.tsx → comboBox/SelectCombobox.tsx} +8 -192
  201. package/src/core/components/shadcn/filters/comboBox/StringListCombobox.tsx +76 -0
  202. package/src/core/components/shadcn/filters/comboBox/TextCombobox.tsx +81 -0
  203. package/src/core/components/shadcn/filters/comboBox/comboBox.tsx +4 -0
  204. package/src/core/components/shadcn/filters/filter/SelectFilter.tsx +161 -0
  205. package/src/core/components/shadcn/filters/{stringListFilter.tsx → filter/StringListFilter.tsx} +7 -7
  206. package/src/core/components/shadcn/filters/{textFilter.tsx → filter/TextFilter.tsx} +17 -11
  207. package/src/core/components/shadcn/filters/filter/dateFilter.tsx +256 -0
  208. package/src/core/components/shadcn/filters/filter-styles.ts +87 -0
  209. package/src/core/components/shadcn/filters/filterBar.tsx +208 -152
  210. package/src/core/components/shadcn/filters/filters.tsx +7 -5
  211. package/src/core/components/shadcn/filters/index.ts +1 -1
  212. package/src/core/components/shadcn/filters/types.ts +2 -0
  213. package/src/core/components/toast/NotificationPanel.tsx +38 -22
  214. package/src/features/agent/PayloadBuilder.tsx +56 -31
  215. package/src/features/agent/chat/ModernAgentConversation.tsx +10 -4
  216. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +7 -6
  217. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +12 -1
  218. package/src/features/agent/chat/ModernAgentOutput/SlidingMessages.tsx +2 -1
  219. package/src/features/agent/chat/ModernAgentOutput/utils.ts +12 -4
  220. package/src/features/facets/DocumentsFacetsNav.tsx +171 -0
  221. package/src/features/facets/RunsFacetsNav.tsx +166 -0
  222. package/src/features/facets/VFacetsNav.tsx +10 -126
  223. package/src/features/facets/VStringFacet.tsx +10 -4
  224. package/src/features/facets/VTypeFacet.tsx +6 -5
  225. package/src/features/facets/VUserFacet.tsx +5 -3
  226. package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +132 -0
  227. package/src/features/facets/index.ts +5 -2
  228. package/src/features/store/collections/CollectionsTable.tsx +3 -2
  229. package/src/features/store/collections/CreateCollection.tsx +17 -15
  230. package/src/features/store/collections/EditCollectionView.tsx +19 -16
  231. package/src/features/store/collections/SelectCollection.tsx +1 -1
  232. package/src/features/store/objects/DocumentPreviewPanel.tsx +0 -1
  233. package/src/features/store/objects/DocumentSearchResults.tsx +80 -11
  234. package/src/features/store/objects/components/ContentOverview.tsx +0 -2
  235. package/src/features/store/objects/components/SelectDocument.tsx +2 -2
  236. package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
  237. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +40 -19
  238. package/src/features/store/objects/upload/DocumentUploadModal.tsx +160 -214
  239. package/src/features/store/types/ObjectSchemaEditor.tsx +15 -0
  240. package/src/features/user/UserInfo.tsx +17 -14
  241. package/src/router/HistoryNavigator.ts +2 -2
  242. package/src/shell/SplashScreen.tsx +41 -0
  243. package/src/shell/VertesiaShell.tsx +27 -0
  244. package/src/shell/index.tsx +6 -0
  245. package/src/shell/login/EnterpriseSigninButton.tsx +106 -0
  246. package/src/shell/login/GitHubSignInButton.tsx +40 -0
  247. package/src/shell/login/GoogleSignInButton.tsx +36 -0
  248. package/src/shell/login/InviteAcceptModal.tsx +78 -0
  249. package/src/shell/login/MicrosoftSigninButton.tsx +30 -0
  250. package/src/shell/login/PreviewIcon.tsx +29 -0
  251. package/src/shell/login/SignInModal.tsx +28 -0
  252. package/src/shell/login/SigninScreen.tsx +162 -0
  253. package/src/shell/login/SignupForm.tsx +178 -0
  254. package/src/shell/login/TerminalLogin.tsx +299 -0
  255. package/src/shell/login/UserInfo.tsx +76 -0
  256. package/src/shell/login/UserSessionMenu.tsx +81 -0
  257. package/src/shell/utils.tsx +7 -0
  258. package/src/widgets/SvgIcon.tsx +44 -0
  259. package/src/widgets/index.ts +7 -6
  260. package/src/widgets/upload/UploadSummary.tsx +3 -4
  261. package/lib/esm/core/components/shadcn/filters/comboBox.js +0 -101
  262. package/lib/esm/core/components/shadcn/filters/comboBox.js.map +0 -1
  263. package/lib/esm/core/components/shadcn/filters/dateFilter.js +0 -36
  264. package/lib/esm/core/components/shadcn/filters/dateFilter.js.map +0 -1
  265. package/lib/esm/core/components/shadcn/filters/selectFilter.js +0 -67
  266. package/lib/esm/core/components/shadcn/filters/selectFilter.js.map +0 -1
  267. package/lib/esm/core/components/shadcn/filters/stringListFilter.js.map +0 -1
  268. package/lib/esm/core/components/shadcn/filters/textFilter.js.map +0 -1
  269. package/lib/esm/features/facets/InteractionFacet.js +0 -39
  270. package/lib/esm/features/facets/InteractionFacet.js.map +0 -1
  271. package/lib/esm/features/facets/TypeOptions.js +0 -19
  272. package/lib/esm/features/facets/TypeOptions.js.map +0 -1
  273. package/lib/esm/features/facets/UserFacet.js +0 -33
  274. package/lib/esm/features/facets/UserFacet.js.map +0 -1
  275. package/lib/types/core/components/shadcn/filters/comboBox.d.ts +0 -22
  276. package/lib/types/features/facets/InteractionFacet.d.ts +0 -9
  277. package/lib/types/features/facets/TypeOptions.d.ts +0 -3
  278. package/lib/types/features/facets/UserFacet.d.ts +0 -11
  279. package/src/core/components/shadcn/filters/dateFilter.tsx +0 -82
  280. package/src/core/components/shadcn/filters/selectFilter.tsx +0 -110
  281. package/src/features/facets/InteractionFacet.tsx +0 -53
  282. package/src/features/facets/TypeOptions.tsx +0 -22
  283. package/src/features/facets/UserFacet.tsx +0 -61
@@ -1,8 +1,8 @@
1
1
  import { Collection, ContentObjectTypeItem, DynamicCollection } from "@vertesia/common";
2
- import { Button, Modal, ModalBody, ModalFooter, ModalTitle, SelectBox, Spinner, useToast } from "@vertesia/ui/core";
2
+ import { Button, MessageBox, VModal, VModalBody, VModalFooter, VModalTitle, VSelectBox, Spinner, useToast, VTooltip } from "@vertesia/ui/core";
3
3
  import { useUserSession } from "@vertesia/ui/session";
4
4
  import { DropZone, UploadSummary } from '@vertesia/ui/widgets';
5
- import { AlertCircleIcon, CheckCircleIcon, FileIcon, FolderIcon, UploadIcon, XCircleIcon } from "lucide-react";
5
+ import { AlertCircleIcon, CheckCircleIcon, FileIcon, FolderIcon, Info, UploadIcon, XCircleIcon } from "lucide-react";
6
6
  import { ReactNode, useEffect, useMemo, useState } from "react";
7
7
  import { FileUploadAction, FileWithMetadata, useSmartFileUploadProcessing } from "./useSmartFileUploadProcessing";
8
8
  import { DocumentUploadResult } from "./useUploadHandler";
@@ -79,6 +79,9 @@ export function DocumentUploadModal({
79
79
  const [overallProgress, setOverallProgress] = useState(0);
80
80
  const [modalKey, setModalKey] = useState(Date.now());
81
81
  const [collectionData, setCollectionData] = useState<Collection | DynamicCollection | undefined>(undefined);
82
+ const [result, setResult] = useState<DocumentUploadResult | null>(null);
83
+ const [_title, setTitle] = useState(title);
84
+ const [_description, setDescription] = useState("");
82
85
 
83
86
  // Fetch collection details if a collectionId is provided
84
87
  useEffect(() => {
@@ -86,17 +89,37 @@ export function DocumentUploadModal({
86
89
  client.store.collections.retrieve(collectionId).then(setCollectionData);
87
90
  }, [collectionId]);
88
91
 
92
+ // Update title and description based on current state
93
+ useEffect(() => {
94
+ if (isUploading) {
95
+ setTitle("Uploading Files");
96
+ setDescription(`${Math.round(overallProgress)}% complete`);
97
+ } else if (uploadComplete) {
98
+ setTitle("Upload Complete");
99
+ setDescription("");
100
+ } else if (processingDone) {
101
+ setTitle("File Analysis Results");
102
+ setDescription(`${files.length} file${files.length !== 1 ? "s" : ""}`);
103
+ } else if (files.length > 0) {
104
+ setTitle(title);
105
+ setDescription("Checking for duplicates and updates");
106
+ } else {
107
+ setTitle(title);
108
+ setDescription("");
109
+ }
110
+ }, [isUploading, uploadComplete, processingDone, title, overallProgress, files.length]);
111
+
89
112
  // Helper function to render collection and folder information
90
113
  const renderLocationInfo = () => {
91
114
  if (!collectionData && !selectedFolder) return null;
92
115
 
93
116
  return (
94
- <div className="mb-4 p-3 bg-blue-50 rounded-md border border-blue-100">
95
- <div className="flex items-center text-blue-700">
96
- <FolderIcon className="h-5 w-5 mr-2" />
117
+ <div className="mb-4 p-3 bg-primary rounded-md border border-primary">
118
+ <div className="flex items-center text-primary">
119
+ <FolderIcon className="size-5 mr-2" />
97
120
  <span className="font-medium">Upload Location:</span>
98
121
  </div>
99
- <div className="ml-7 text-sm text-blue-700 mt-1">
122
+ <div className="ml-7 text-sm text-primary mt-1">
100
123
  {collectionData && (
101
124
  <div className="flex items-center">
102
125
  <span className="mr-1">Collection:</span>
@@ -132,21 +155,25 @@ export function DocumentUploadModal({
132
155
  // Reset state when modal opens/closes
133
156
  useEffect(() => {
134
157
  if (isOpen) {
158
+ // Always reset state first
159
+ setProcessedFiles([]);
160
+ setProcessingDone(false);
161
+ setSelectedType(null);
162
+ setFileStatuses([]);
163
+ setIsUploading(false);
164
+ setUploadComplete(false);
165
+ setOverallProgress(0);
166
+ setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
167
+ setResult(null);
168
+ setTitle(title);
169
+ setDescription("");
170
+
135
171
  // Set initial files if provided
136
172
  if (initialFiles && initialFiles.length > 0) {
137
173
  setFiles(initialFiles);
138
174
  processFiles(initialFiles);
139
175
  } else {
140
- // Reset state
141
176
  setFiles([]);
142
- setProcessedFiles([]);
143
- setProcessingDone(false);
144
- setSelectedType(null);
145
- setFileStatuses([]);
146
- setIsUploading(false);
147
- setUploadComplete(false);
148
- setOverallProgress(0);
149
- setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
150
177
  }
151
178
 
152
179
  // Create a new key to ensure the modal is fresh
@@ -166,6 +193,10 @@ export function DocumentUploadModal({
166
193
  setUploadComplete(false);
167
194
  setOverallProgress(0);
168
195
  setProcessingStats({ toCreate: 0, toUpdate: 0, toSkip: 0 });
196
+ setResult(null);
197
+ setTitle(title);
198
+ setDescription("");
199
+ setModalKey(Date.now());
169
200
 
170
201
  // Call the provided onClose function
171
202
  onClose();
@@ -511,11 +542,48 @@ export function DocumentUploadModal({
511
542
  status: failedCount > 0 ? "warning" : "success",
512
543
  duration: 5000,
513
544
  });
545
+ setResult(result);
546
+ };
514
547
 
515
- // Call the uploadComplete callback if provided
516
- if (onUploadComplete) {
517
- onUploadComplete(result);
518
- }
548
+ const typeSelection = () => {
549
+ return (
550
+ <div className="mb-4">
551
+ <label className="block text-sm font-medium mb-2">
552
+ Content Type <span className="text-muted font-normal">(Optional)</span>
553
+ <VTooltip
554
+ description="Select a content type to apply to the uploaded files. If left empty, Vertesia will automatically detect the type based on file content."
555
+ placement="top" size="xs"
556
+ >
557
+ <Info className="size-3 ml-2" />
558
+ </VTooltip>
559
+ </label>
560
+ <VSelectBox
561
+ options={types}
562
+ value={selectedType}
563
+ optionLabel={(type) => (type ? type.name : "Select a content type")}
564
+ placeholder="Select a content type or leave empty for automatic detection"
565
+ onChange={(selected) => setSelectedType(selected === undefined ? null : selected)}
566
+ filterBy="name"
567
+ isClearable
568
+ />
569
+ {selectedType ? (
570
+ <></>
571
+ ) : (
572
+ <div className="p-2 rounded-md">
573
+ <div className="flex items-center text-attention">
574
+ <CheckCircleIcon className="size-4 mr-1" />
575
+ Automatic Type Detection
576
+ <VTooltip
577
+ description="Vertesia will analyze the content and select the most appropriate type. This is recommended for most uploads and ensures optimal processing."
578
+ placement="top" size="xs"
579
+ >
580
+ <Info className="size-3 ml-2" />
581
+ </VTooltip>
582
+ </div>
583
+ </div>
584
+ )}
585
+ </div>
586
+ )
519
587
  };
520
588
 
521
589
  // Determine what content to show based on the current state
@@ -523,67 +591,22 @@ export function DocumentUploadModal({
523
591
  // When showing only type selection, skip directly to the type selection UI
524
592
  if (showTypeSelectionOnly) {
525
593
  return (
526
- <ModalBody className="p-6">
594
+ <VModalBody>
527
595
  {children}
528
596
 
529
597
  {/* Collection and folder information if available */}
530
598
  {renderLocationInfo()}
531
599
 
532
600
  {/* Type selection */}
533
- <div className="mb-4">
534
- <label className="block text-sm font-medium mb-2">
535
- Content Type <span className="text-gray-500 font-normal">(Optional)</span>
536
- </label>
537
- <SelectBox
538
- options={types}
539
- value={selectedType}
540
- optionLabel={(type) => (type ? type.name : "Select a content type")}
541
- placeholder="Select a content type or leave empty for automatic detection"
542
- onChange={(selected) => setSelectedType(selected === undefined ? null : selected)}
543
- filterBy="name"
544
- isClearable
545
- />
546
-
547
- <div className="mt-2 text-sm text-blue-600 flex items-center">
548
- <CheckCircleIcon className="h-4 w-4 mr-1" />
549
- <span>
550
- <strong>Type selection is optional.</strong> Leave empty to let Vertesia choose the
551
- appropriate type
552
- </span>
553
- </div>
554
- </div>
555
-
556
- {selectedType ? (
557
- <div className="text-sm text-gray-500 bg-gray-50 p-3 rounded-md mb-4">
558
- <div className="font-medium">{selectedType.name}</div>
559
- {selectedType.description && <div className="mt-1">{selectedType.description}</div>}
560
- </div>
561
- ) : (
562
- <div className="text-sm text-blue-600 bg-blue-50 p-3 rounded-md mb-4">
563
- <div className="font-medium flex items-center">
564
- <CheckCircleIcon className="h-5 w-5 mr-1" />
565
- Automatic Type Detection
566
- </div>
567
- <div className="mt-1">
568
- <p>
569
- <strong>
570
- Vertesia will analyze the content and select the most appropriate type.
571
- </strong>
572
- </p>
573
- <p className="mt-1">
574
- This is recommended for most uploads and ensures optimal processing.
575
- </p>
576
- </div>
577
- </div>
578
- )}
579
- </ModalBody>
601
+ {typeSelection()}
602
+ </VModalBody>
580
603
  );
581
604
  }
582
605
 
583
- // Step 1: File selection
606
+ // Step 1: File selection #todo: update styles
584
607
  if (files.length === 0 && !hideFileSelection) {
585
608
  return (
586
- <ModalBody className="flex flex-col items-center justify-center p-8">
609
+ <VModalBody className="flex flex-col items-center justify-center p-8">
587
610
  {/* Collection and folder information if available */}
588
611
  {renderLocationInfo()}
589
612
 
@@ -594,22 +617,19 @@ export function DocumentUploadModal({
594
617
  className="w-full h-64"
595
618
  />
596
619
  {children}
597
- </ModalBody>
620
+ </VModalBody>
598
621
  );
599
622
  }
600
623
 
601
624
  // Step 2: File processing and type selection
602
625
  if (!isUploading && !uploadComplete) {
603
626
  return (
604
- <ModalBody className="p-6">
627
+ <VModalBody>
605
628
  {!processingDone ? (
606
629
  // File processing in progress
607
- <div className="flex flex-col items-center justify-center py-8">
630
+ <div className="flex flex-col items-center justify-center py-4">
608
631
  <Spinner size="lg" className="mb-4" />
609
632
  <div className="text-lg font-medium">Analyzing files...</div>
610
- <div className="text-sm text-muted mt-2">
611
- Checking for duplicates and updates
612
- </div>
613
633
  </div>
614
634
  ) : (
615
635
  // Processing complete, show type selection
@@ -618,33 +638,26 @@ export function DocumentUploadModal({
618
638
  {renderLocationInfo()}
619
639
 
620
640
  <div className="mb-4">
621
- <div className="flex justify-between items-center mb-2">
622
- <div className="text-lg font-medium">File Analysis Results</div>
623
- <div className="text-sm text-muted">
624
- {files.length} file{files.length !== 1 ? "s" : ""}
625
- </div>
626
- </div>
627
-
628
641
  {/* File statistics */}
629
- <div className="bg-color-muted/10 p-4 rounded-md mb-4">
642
+ <div className="p-4 rounded-md mb-4">
630
643
  <div className="grid grid-cols-3 gap-4">
631
644
  <div className="flex flex-col items-center">
632
- <div className="flex items-center">
633
- <UploadIcon className="h-5 w-5 text-blue-500 mr-2" />
645
+ <div className="flex items-center gap-2">
646
+ <UploadIcon className="size-5 text-primary" />
634
647
  <span className="font-medium">New</span>
635
648
  </div>
636
649
  <div className="text-2xl font-semibold">{processingStats.toCreate}</div>
637
650
  </div>
638
651
  <div className="flex flex-col items-center">
639
- <div className="flex items-center">
640
- <CheckCircleIcon className="h-5 w-5 text-green-500 mr-2" />
652
+ <div className="flex items-center gap-2">
653
+ <CheckCircleIcon className="size-5 text-success" />
641
654
  <span className="font-medium">Update</span>
642
655
  </div>
643
656
  <div className="text-2xl font-semibold">{processingStats.toUpdate}</div>
644
657
  </div>
645
658
  <div className="flex flex-col items-center">
646
- <div className="flex items-center">
647
- <AlertCircleIcon className="h-5 w-5 text-yellow-500 mr-2" />
659
+ <div className="flex items-center gap-2">
660
+ <AlertCircleIcon className="size-5 text-mixer-attention/40" />
648
661
  <span className="font-medium">Skip</span>
649
662
  </div>
650
663
  <div className="text-2xl font-semibold">{processingStats.toSkip}</div>
@@ -654,120 +667,51 @@ export function DocumentUploadModal({
654
667
  </div>
655
668
 
656
669
  {/* Type selection */}
657
- <div className="mb-4">
658
- <label className="block text-sm font-medium mb-2">
659
- Content Type <span className="text-gray-500 font-normal">(Optional)</span>
660
- </label>
661
- <SelectBox
662
- options={types}
663
- value={selectedType}
664
- optionLabel={(type) => (type ? type.name : "Select a content type")}
665
- placeholder="Select a content type or leave empty for automatic detection"
666
- onChange={(selected) => setSelectedType(selected === undefined ? null : selected)}
667
- filterBy="name"
668
- isClearable
669
- />
670
-
671
- <div className="mt-2 text-sm text-blue-600 flex items-center">
672
- <CheckCircleIcon className="h-4 w-4 mr-1" />
670
+ {typeSelection()}
671
+
672
+ <MessageBox
673
+ className="mb-4"
674
+ status="info"
675
+ >
676
+ {processingStats.toCreate + processingStats.toUpdate > 0 ? (
677
+ <div className="space-y-1">
678
+ <p>
679
+ {processingStats.toCreate + processingStats.toUpdate} file{processingStats.toCreate + processingStats.toUpdate > 1 ? "s are" : " is"} ready
680
+ to process
681
+ </p>
682
+ <p>
683
+ {processingStats.toSkip > 0 &&
684
+ `${processingStats.toSkip} file${processingStats.toSkip > 1 ? "s are" : " is"} already in the system and will be skipped.`}
685
+ </p>
686
+ </div>
687
+ ) : processingStats.toSkip > 0 ? (
673
688
  <span>
674
- <strong>Type selection is optional.</strong> Leave empty to let Vertesia choose
675
- the appropriate type
689
+ All {processingStats.toSkip} file(s) already exist in the system and
690
+ will be skipped. You can proceed to view the results.
676
691
  </span>
677
- </div>
678
- </div>
692
+ ) : (
693
+ <span>No files to process.</span>
694
+ )}
695
+ </MessageBox>
679
696
 
680
- {selectedType ? (
681
- <div className="p-4 bg-gray-50 rounded-md border border-gray-100 mb-4">
682
- <div className="font-medium mb-2">Files to process with selected type:</div>
683
- <div className="text-sm">
684
- {processingStats.toCreate + processingStats.toUpdate > 0 ? (
685
- <div className="space-y-1">
686
- <p>
687
- {processingStats.toCreate + processingStats.toUpdate} file(s) ready
688
- to process
689
- {processingStats.toSkip > 0 &&
690
- ` (${processingStats.toSkip} will be skipped as they already exist)`}
691
- </p>
692
- <p className="text-green-600">
693
- Files will be uploaded with type:{" "}
694
- <strong>{selectedType.name}</strong>
695
- </p>
696
- {selectedType.description && (
697
- <p className="text-gray-500 mt-1">{selectedType.description}</p>
698
- )}
699
- </div>
700
- ) : processingStats.toSkip > 0 ? (
701
- <span>
702
- All {processingStats.toSkip} file(s) already exist in the system and
703
- will be skipped. You can proceed to view the results.
704
- </span>
705
- ) : (
706
- <span>No files to process.</span>
707
- )}
708
- </div>
709
- </div>
710
- ) : (
711
- <div className="p-4 bg-blue-50 rounded-md border border-blue-100 mb-4">
712
- <div className="font-medium mb-2 flex items-center text-blue-700">
713
- <CheckCircleIcon className="h-5 w-5 mr-1" />
714
- Automatic Type Detection
715
- </div>
716
- <div className="text-sm text-blue-700">
717
- {processingStats.toCreate + processingStats.toUpdate > 0 ? (
718
- <div className="space-y-1">
719
- <p>
720
- {processingStats.toCreate + processingStats.toUpdate} file(s) ready
721
- to process
722
- {processingStats.toSkip > 0 &&
723
- ` (${processingStats.toSkip} will be skipped as they already exist)`}
724
- </p>
725
- <p className="mt-2">
726
- <strong>
727
- Vertesia will analyze each file and select the most appropriate
728
- type.
729
- </strong>
730
- </p>
731
- <p className="mt-1">
732
- This is recommended for most uploads and ensures optimal processing.
733
- </p>
734
- </div>
735
- ) : processingStats.toSkip > 0 ? (
736
- <span>
737
- All {processingStats.toSkip} file(s) already exist in the system and
738
- will be skipped. You can proceed to view the results.
739
- </span>
740
- ) : (
741
- <span>No files to process.</span>
742
- )}
743
- </div>
744
- </div>
745
- )}
746
697
  </>
747
698
  )}
748
- </ModalBody>
699
+ </VModalBody>
749
700
  );
750
701
  }
751
702
 
752
- // Step 3: Upload in progress
703
+ // Step 3: Upload in progress #todo: update styles
753
704
  if (isUploading) {
754
705
  return (
755
- <ModalBody className="p-6">
706
+ <VModalBody>
756
707
  {/* Collection and folder information if available */}
757
708
  {renderLocationInfo()}
758
709
 
759
710
  <div className="mb-4">
760
- <div className="flex justify-between items-center mb-2">
761
- <div className="text-lg font-medium">Uploading Files</div>
762
- <div className="text-sm text-muted">
763
- {Math.round(overallProgress)}% complete
764
- </div>
765
- </div>
766
-
767
711
  {/* Progress bar */}
768
- <div className="h-2 bg-color-muted/20 rounded-full overflow-hidden">
712
+ <div className="h-2 bg-muted/20 rounded-full overflow-hidden">
769
713
  <div
770
- className="h-full bg-color-primary rounded-full"
714
+ className="h-full bg-primary rounded-full"
771
715
  style={{ width: `${overallProgress}%` }}
772
716
  />
773
717
  </div>
@@ -778,17 +722,17 @@ export function DocumentUploadModal({
778
722
  {fileStatuses.map((fileStatus, index) => (
779
723
  <div
780
724
  key={`${fileStatus.file.name}-${index}`}
781
- className="flex items-center py-2 border-b border-color-border last:border-b-0"
725
+ className="flex items-center py-2 border-b border-border last:border-b-0"
782
726
  >
783
727
  <div className="mr-3">
784
728
  {fileStatus.status === "pending" && (
785
- <FileIcon className="h-5 w-5 text-muted" />
729
+ <FileIcon className="size-5 text-muted" />
786
730
  )}
787
731
  {fileStatus.status === "uploading" && <Spinner size="sm" />}
788
732
  {fileStatus.status === "success" && (
789
- <CheckCircleIcon className="h-5 w-5 text-green-500" />
733
+ <CheckCircleIcon className="size-5 text-success" />
790
734
  )}
791
- {fileStatus.status === "error" && <XCircleIcon className="h-5 w-5 text-red-500" />}
735
+ {fileStatus.status === "error" && <XCircleIcon className="size-5 text-destructive" />}
792
736
  </div>
793
737
  <div className="flex-1 min-w-0">
794
738
  <div className="truncate font-medium">{fileStatus.file.name}</div>
@@ -807,16 +751,14 @@ export function DocumentUploadModal({
807
751
  </div>
808
752
  ))}
809
753
  </div>
810
- </ModalBody>
754
+ </VModalBody>
811
755
  );
812
756
  }
813
757
 
814
758
  // Step 4: Upload complete, show results
815
759
  return (
816
- <ModalBody className="p-6">
760
+ <VModalBody>
817
761
  <div className="mb-4">
818
- <div className="text-lg font-medium mb-2">Upload Complete</div>
819
-
820
762
  {/* Collection and folder information if available */}
821
763
  {renderLocationInfo()}
822
764
 
@@ -847,7 +789,7 @@ export function DocumentUploadModal({
847
789
  collection={collectionData?.name}
848
790
  />
849
791
  </div>
850
- </ModalBody>
792
+ </VModalBody>
851
793
  );
852
794
  };
853
795
 
@@ -855,7 +797,7 @@ export function DocumentUploadModal({
855
797
  // Type-selection-only mode
856
798
  if (showTypeSelectionOnly) {
857
799
  return (
858
- <ModalFooter>
800
+ <VModalFooter>
859
801
  <Button variant="ghost" onClick={handleClose}>
860
802
  Cancel
861
803
  </Button>
@@ -884,18 +826,18 @@ export function DocumentUploadModal({
884
826
  >
885
827
  {selectedType ? `Use ${selectedType.name}` : "Use Automatic Type Detection"}
886
828
  </Button>
887
- </ModalFooter>
829
+ </VModalFooter>
888
830
  );
889
831
  }
890
832
 
891
833
  // File selection step - only show cancel
892
834
  if (files.length === 0 && !hideFileSelection) {
893
835
  return (
894
- <ModalFooter>
836
+ <VModalFooter>
895
837
  <Button variant="ghost" onClick={handleClose}>
896
838
  Cancel
897
839
  </Button>
898
- </ModalFooter>
840
+ </VModalFooter>
899
841
  );
900
842
  }
901
843
 
@@ -905,39 +847,36 @@ export function DocumentUploadModal({
905
847
  const canUpload = processingDone;
906
848
 
907
849
  return (
908
- <ModalFooter>
850
+ <VModalFooter>
909
851
  <Button variant="ghost" onClick={handleClose}>
910
852
  Cancel
911
853
  </Button>
912
854
  <Button
913
855
  disabled={!canUpload}
914
856
  onClick={handleUpload}
915
- className={!selectedType ? "bg-blue-600 hover:bg-blue-700" : ""}
916
857
  >
917
858
  {processingStats.toCreate + processingStats.toUpdate > 0
918
- ? selectedType
919
- ? `Upload with ${selectedType.name}`
920
- : "Upload with Automatic Type Detection"
859
+ ? "Upload"
921
860
  : "Continue"}
922
861
  </Button>
923
- </ModalFooter>
862
+ </VModalFooter>
924
863
  );
925
864
  }
926
865
 
927
866
  // Upload in progress - can't cancel
928
867
  if (isUploading) {
929
868
  return (
930
- <ModalFooter>
869
+ <VModalFooter>
931
870
  <Button variant="ghost" disabled>
932
871
  Uploading...
933
872
  </Button>
934
- </ModalFooter>
873
+ </VModalFooter>
935
874
  );
936
875
  }
937
876
 
938
877
  // Upload complete - close or upload more
939
878
  return (
940
- <ModalFooter>
879
+ <VModalFooter>
941
880
  <Button
942
881
  variant="ghost"
943
882
  onClick={() => {
@@ -955,16 +894,23 @@ export function DocumentUploadModal({
955
894
  >
956
895
  Upload More
957
896
  </Button>
958
- <Button onClick={handleClose}>Close</Button>
959
- </ModalFooter>
897
+ <Button onClick={() => {
898
+ if (onUploadComplete && result) {
899
+ onUploadComplete(result);
900
+ }
901
+ handleClose();
902
+ }}>
903
+ Close
904
+ </Button>
905
+ </VModalFooter>
960
906
  );
961
907
  };
962
908
 
963
909
  return (
964
- <Modal key={modalKey} isOpen={isOpen} onClose={handleClose} className="w-full max-w-3xl mx-auto">
965
- <ModalTitle>{title}</ModalTitle>
910
+ <VModal key={modalKey} isOpen={isOpen} onClose={handleClose} className="mx-auto">
911
+ <VModalTitle description={_description}>{_title}</VModalTitle>
966
912
  {renderModalContent()}
967
913
  {renderModalFooter()}
968
- </Modal>
914
+ </VModal>
969
915
  );
970
916
  }
@@ -6,6 +6,7 @@ import { json } from '@codemirror/lang-json';
6
6
  import { CodeMirrorEditor, EditorApi, SchemaEditor, useSchema } from '@vertesia/ui/widgets';
7
7
  import { Button, useToast } from '@vertesia/ui/core';
8
8
  import { ContentObjectType } from '@vertesia/common';
9
+ import { Ajv } from "ajv";
9
10
 
10
11
  const CODE_MIRROR_EXTENSIONS = [basicSetup, json()];
11
12
 
@@ -69,6 +70,7 @@ export function ObjectSchemaEditor({ objectType, onSchemaUpdate }: ObjectSchemaE
69
70
  const value = editorRef.current.getValue();
70
71
  try {
71
72
  const newSchema = contentToJson(value);
73
+ validateSchema(newSchema);
72
74
  schema.replaceSchema(newSchema);
73
75
  } catch (err: any) {
74
76
  toast({
@@ -124,3 +126,16 @@ function contentToJson(content: string | undefined | null) {
124
126
 
125
127
  return JSON.parse(content.trim());
126
128
  }
129
+
130
+ const validateSchema = (schema: Record<string, any>) => {
131
+ try {
132
+ const ajv = new Ajv({
133
+ strict: true, // Enable strict mode to ensure all properties are validated
134
+ });
135
+ // Compile the schema. This implicitly validates the schema definition
136
+ // against the JSON Schema draft that ajv supports by default.
137
+ ajv.compile(schema);
138
+ } catch (error: any) {
139
+ throw new Error(`Invalid JSON Schema definition: ${error.message}`);
140
+ }
141
+ };