@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
@@ -8,18 +8,146 @@ import { ListFilter } from "lucide-react";
8
8
  import { Filter, FilterGroup } from "./types";
9
9
  import Filters from "./filters";
10
10
 
11
- import TextFilter from "./textFilter";
12
- import DateFilter from "./dateFilter";
13
- import SelectFilter from "./selectFilter";
14
- import StringListFilter from "./stringListFilter";
11
+ import TextFilter from "./filter/TextFilter";
12
+ import DateFilter from "./filter/dateFilter";
13
+ import SelectFilter from "./filter/SelectFilter";
14
+ import StringListFilter from "./filter/StringListFilter";
15
15
 
16
- interface FilterBarProps {
16
+ const FilterContext = React.createContext<{
17
17
  filters: Filter[];
18
18
  setFilters: Dispatch<SetStateAction<Filter[]>>;
19
19
  filterGroups: FilterGroup[];
20
+ }>({} as any);
21
+
22
+ interface FilterProviderProps {
23
+ filters: Filter[];
24
+ setFilters: Dispatch<SetStateAction<Filter[]>>;
25
+ filterGroups: FilterGroup[];
26
+ children: React.ReactNode;
20
27
  }
21
28
 
22
- export function FilterBar({ filters, setFilters, filterGroups }: FilterBarProps) {
29
+ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterProviderProps) => {
30
+ const url = new URL(window.location.href);
31
+ const searchParams = url.searchParams;
32
+
33
+ useEffect(() => {
34
+ try {
35
+ const params = new URLSearchParams(searchParams.toString());
36
+ if (filters.length > 0) {
37
+ // Convert filters to format with array indicators: filterName:value,value;filterName2:value
38
+ // Arrays are prefixed with []: filterName:[value1,value2]
39
+ const filterString = filters.map(filter => {
40
+ let values;
41
+ if (filter.type === 'stringList' && Array.isArray(filter.value) && typeof filter.value[0] === 'string') {
42
+ // Handle stringList with direct string array - always array format
43
+ values = `[${(filter.value as string[]).map(item => encodeURIComponent(item)).join(',')}]`;
44
+ } else if (Array.isArray(filter.value)) {
45
+ if (filter.multiple || filter.value.length > 1) {
46
+ // Handle multiple values - use array format
47
+ values = `[${filter.value.map((item: any) => encodeURIComponent(item.value || '')).join(',')}]`;
48
+ } else {
49
+ // Single value in array - don't use array format
50
+ const firstValue = filter.value[0];
51
+ if (typeof firstValue === 'string') {
52
+ values = encodeURIComponent(firstValue);
53
+ } else {
54
+ values = encodeURIComponent(firstValue?.value || '');
55
+ }
56
+ }
57
+ } else {
58
+ values = encodeURIComponent(filter.value || '');
59
+ }
60
+ return `${encodeURIComponent(filter.name)}:${values}`;
61
+ }).join(';');
62
+ params.set('filters', filterString);
63
+ } else {
64
+ params.delete('filters');
65
+ }
66
+
67
+ const newUrl = `${window.location.pathname}?${params.toString()}`;
68
+ window.history.replaceState({}, '', newUrl);
69
+ } catch (error) {
70
+ console.error("Failed to update URL with filters:", error);
71
+ }
72
+ }, [filters]);
73
+
74
+ useEffect(() => {
75
+ const filtersParam = searchParams.get('filters');
76
+ if (filtersParam) {
77
+ try {
78
+ // Parse format with array indicators: filterName:value or filterName:[value1,value2]
79
+ const filterPairs = filtersParam.split(';');
80
+ const parsedFilters = filterPairs.map(pair => {
81
+ const [encodedName, valuesString] = pair.split(':');
82
+ const name = decodeURIComponent(encodedName);
83
+
84
+ let values: string[];
85
+ // Check if it's an array format [value1,value2]
86
+ if (valuesString.startsWith('[') && valuesString.endsWith(']')) {
87
+ // Array format - remove brackets and split by comma
88
+ const arrayContent = valuesString.slice(1, -1); // Remove [ and ]
89
+ values = arrayContent ? arrayContent.split(',').map(encodedValue => decodeURIComponent(encodedValue)) : [];
90
+ } else {
91
+ // Single value format
92
+ values = [decodeURIComponent(valuesString)];
93
+ }
94
+
95
+ const group = filterGroups.find(g => g.name === name);
96
+ let filterValue;
97
+
98
+ if (group?.type === 'stringList') {
99
+ // For stringList, return direct string array
100
+ filterValue = values;
101
+ } else if (group?.type === 'text') {
102
+ // For text, return FilterOption array (single value for text inputs)
103
+ filterValue = values.length === 1 ? [{ value: values[0], label: values[0] }] :
104
+ values.map(value => ({ value, label: value }));
105
+ } else {
106
+ // For other types, find options with labels
107
+ filterValue = values.map(value => {
108
+ const matchingOption = group?.options?.find(opt => opt.value === value);
109
+ let label = value;
110
+
111
+ if (matchingOption?.label) {
112
+ label = String(matchingOption.label);
113
+ } else if (matchingOption?.labelRenderer) {
114
+ label = String(matchingOption.labelRenderer(value));
115
+ } else if (group?.labelRenderer) {
116
+ label = String(group.labelRenderer(value));
117
+ }
118
+
119
+ return {
120
+ value,
121
+ label
122
+ };
123
+ });
124
+ }
125
+
126
+ return {
127
+ name,
128
+ type: group?.type || 'select',
129
+ placeholder: group?.placeholder,
130
+ value: filterValue,
131
+ multiple: group?.multiple || false
132
+ };
133
+ });
134
+
135
+ setFilters(parsedFilters);
136
+ } catch (error) {
137
+ console.error("Failed to parse filters from URL:", error);
138
+ }
139
+ }
140
+ }, []);
141
+
142
+ return (
143
+ <FilterContext.Provider value={{ filters, setFilters, filterGroups }}>
144
+ {children}
145
+ </FilterContext.Provider>
146
+ );
147
+ };
148
+
149
+ const FilterBtn = ({ className }: { className?: string }) => {
150
+ const { filters, setFilters, filterGroups } = React.useContext(FilterContext);
23
151
  const [open, setOpen] = React.useState(false);
24
152
  const [selectedView, setSelectedView] = React.useState<string | null>(null);
25
153
  const [commandInput, setCommandInput] = React.useState("");
@@ -42,7 +170,7 @@ export function FilterBar({ filters, setFilters, filterGroups }: FilterBarProps)
42
170
  return filter.name === group.name;
43
171
  }
44
172
  return filter.name === group.name &&
45
- (Array.isArray(filter.value) && typeof filter.value[0] === 'string'
173
+ (Array.isArray(filter.value) && typeof filter.value[0] === 'string'
46
174
  ? filter.value.some(val => val === option.value)
47
175
  : filter.value.some(val => (val as any).value === option.value));
48
176
  })
@@ -89,23 +217,10 @@ export function FilterBar({ filters, setFilters, filterGroups }: FilterBarProps)
89
217
  }
90
218
  };
91
219
 
92
- const ButtonClearFilter = () => {
93
- return (
94
- <div className="flex gap-2 items-center">
95
- <Button
96
- variant="outline"
97
- size="xs"
98
- className="transition group"
99
- onClick={() => setFilters([])}
100
- >
101
- Clear All
102
- </Button>
103
- </div>
104
- );
105
- };
106
-
107
220
  const renderFilterOptions = () => {
108
- if (!selectedView) return null;
221
+ if (!selectedView) {
222
+ return null;
223
+ }
109
224
 
110
225
  const selectedGroupType = filterGroups.find(g => g.name === selectedView)?.type;
111
226
 
@@ -155,138 +270,79 @@ export function FilterBar({ filters, setFilters, filterGroups }: FilterBarProps)
155
270
  }
156
271
  };
157
272
 
158
- const url = new URL(window.location.href);
159
- const searchParams = url.searchParams;
160
- useEffect(() => {
161
- try {
162
- const params = new URLSearchParams(searchParams.toString());
163
- if (filters.length > 0) {
164
- // Convert filters to simple format with URL-safe encoding: filterName:value,value;filterName2:value
165
- const filterString = filters.map(filter => {
166
- let values;
167
- if (filter.type === 'stringList' && Array.isArray(filter.value) && typeof filter.value[0] === 'string') {
168
- // Handle stringList with direct string array
169
- values = (filter.value as string[]).map(item => encodeURIComponent(item)).join(',');
170
- } else if (Array.isArray(filter.value)) {
171
- // Handle other types with FilterOption array
172
- values = filter.value.map((item: any) => encodeURIComponent(item.value || '')).join(',');
173
- } else {
174
- values = encodeURIComponent(filter.value || '');
175
- }
176
- return `${encodeURIComponent(filter.name)}:${values}`;
177
- }).join(';');
178
- params.set('filters', filterString);
179
- } else {
180
- params.delete('filters');
181
- }
182
-
183
- const newUrl = `${window.location.pathname}?${params.toString()}`;
184
- window.history.replaceState({}, '', newUrl);
185
- } catch (error) {
186
- console.error("Failed to update URL with filters:", error);
187
- }
188
- }, [filters]);
189
-
190
- useEffect(() => {
191
- const filtersParam = searchParams.get('filters');
192
- if (filtersParam) {
193
- try {
194
- // Parse simple format with URL-safe decoding: filterName:value,value;filterName2:value
195
- const filterPairs = filtersParam.split(';');
196
- const parsedFilters = filterPairs.map(pair => {
197
- const [encodedName, valuesString] = pair.split(':');
198
- const name = decodeURIComponent(encodedName);
199
- const values = valuesString.split(',').map(encodedValue => decodeURIComponent(encodedValue));
200
-
201
- const group = filterGroups.find(g => g.name === name);
202
- let filterValue;
203
-
204
- if (group?.type === 'stringList') {
205
- // For stringList, return direct string array
206
- filterValue = values;
207
- } else if (group?.type === 'text') {
208
- // For text, return FilterOption array
209
- filterValue = values.map(value => ({ value, label: value }));
210
- } else {
211
- // For other types, find options with labels
212
- filterValue = values.map(value => {
213
- const matchingOption = group?.options?.find(opt => opt.value === value);
214
- let label = value;
215
-
216
- if (matchingOption?.label) {
217
- label = String(matchingOption.label);
218
- } else if (matchingOption?.labelRenderer) {
219
- label = String(matchingOption.labelRenderer(value));
220
- } else if (group?.labelRenderer) {
221
- label = String(group.labelRenderer(value));
222
- }
223
-
224
- return {
225
- value,
226
- label
227
- };
228
- });
273
+ return (
274
+ <Popover _open={open} onOpenChange={handleOpen}>
275
+ <PopoverTrigger asChild>
276
+ <Button
277
+ variant="outline"
278
+ role="combobox"
279
+ aria-expanded={open}
280
+ size="md"
281
+ className={cn(
282
+ "transition group flex gap-1.5",
283
+ className
284
+ )}
285
+ >
286
+ <ListFilter className="size-4 shrink-0 transition-all text-muted" />
287
+ {"Filter"}
288
+ </Button>
289
+ </PopoverTrigger>
290
+ <PopoverContent className="w-[300px] p-0" align="start">
291
+ <Command>
292
+ {
293
+ filterGroups.find(group => group.name === selectedView)?.type === "select" && (
294
+ <CommandInput
295
+ placeholder={selectedView ? `Filter by ${selectedView}` : "Filter..."}
296
+ className="h-9 ring-0"
297
+ value={commandInput}
298
+ onValueChange={(value) => {
299
+ setCommandInput(value);
300
+ }}
301
+ ref={commandInputRef}
302
+ autoFocus={true}
303
+ />
304
+ )
229
305
  }
230
-
231
- return {
232
- name,
233
- type: group?.type || 'select',
234
- placeholder: group?.placeholder,
235
- value: filterValue
236
- };
237
- });
238
-
239
- setFilters(parsedFilters);
240
- } catch (error) {
241
- console.error("Failed to parse filters from URL:", error);
242
- }
243
- }
244
- }, []);
306
+ <CommandList className="max-h-[300px] overflow-y-auto">
307
+ <CommandGroup>
308
+ {!selectedView ? getAvailableFilterGroups() : renderFilterOptions()}
309
+ </CommandGroup>
310
+ </CommandList>
311
+ </Command>
312
+ </PopoverContent>
313
+ </Popover>
314
+ );
315
+ };
245
316
 
317
+ const FilterBar = ({ className }: { className?: string }) => {
318
+ const { filters, setFilters, filterGroups } = React.useContext(FilterContext);
319
+
246
320
  return (
247
- <div className="flex gap-2 flex-wrap justify-start w-full items-center">
248
- <div className="flex gap-2 items-center">
249
- <Popover _open={open} onOpenChange={handleOpen}>
250
- <PopoverTrigger asChild>
251
- <Button
252
- variant="ghost"
253
- role="combobox"
254
- aria-expanded={open}
255
- size="md"
256
- className={cn(
257
- "transition group flex gap-1.5",
258
- )}
259
- >
260
- <ListFilter className="size-4 shrink-0 transition-all text-muted" />
261
- {"Filter"}
262
- </Button>
263
- </PopoverTrigger>
264
- <PopoverContent className="w-[300px] p-0" align="start">
265
- <Command>
266
- {filterGroups.find(group => group.name === selectedView)?.type === "select" ? (
267
- <CommandInput
268
- placeholder={selectedView ? `Filter by ${selectedView}` : "Filter..."}
269
- className="h-9 ring-0"
270
- value={commandInput}
271
- onValueChange={(value) => {
272
- setCommandInput(value);
273
- }}
274
- ref={commandInputRef}
275
- autoFocus={true}
276
- />
277
- ) : null}
278
-
279
- <CommandList className="max-h-[300px] overflow-y-auto">
280
- <CommandGroup>
281
- {!selectedView ? getAvailableFilterGroups() : renderFilterOptions()}
282
- </CommandGroup>
283
- </CommandList>
284
- </Command>
285
- </PopoverContent>
286
- </Popover>
287
- </div>
321
+ <div className={cn(className)}>
288
322
  <Filters filters={filters} setFilters={setFilters} filterGroups={filterGroups} />
289
- {filters.filter((filter) => filter.value?.length > 0).length > 0 && <ButtonClearFilter />}
290
323
  </div>
291
324
  );
292
- }
325
+ };
326
+
327
+ const FilterClear = ({ className }: { className?: string }) => {
328
+ const { filters, setFilters } = React.useContext(FilterContext);
329
+
330
+ const hasActiveFilters = filters.filter((filter) => filter.value?.length > 0).length > 0;
331
+
332
+ if (!hasActiveFilters) {
333
+ return null;
334
+ }
335
+
336
+ return (
337
+ <Button
338
+ variant="outline"
339
+ size="xs"
340
+ className={cn("transition group", className)}
341
+ onClick={() => setFilters([])}
342
+ >
343
+ Clear All
344
+ </Button>
345
+ );
346
+ };
347
+
348
+ export { FilterProvider, FilterBtn, FilterBar, FilterClear };
@@ -2,7 +2,7 @@ import { X } from "lucide-react";
2
2
  import { Dispatch, SetStateAction } from "react";
3
3
  import { Button } from "../button";
4
4
 
5
- import { DateCombobox, SelectionCombobox, TextCombobox, StringListCombobox } from "./comboBox";
5
+ import { DateCombobox, SelectionCombobox, TextCombobox, StringListCombobox } from "./comboBox/comboBox";
6
6
  import { Filter, FilterGroup, FilterOption } from "./types";
7
7
  import dayjs from "dayjs";
8
8
 
@@ -22,15 +22,17 @@ function generateComboboxOptions(
22
22
  return (
23
23
  <DateCombobox
24
24
  filterValues={Array.isArray(filter.value) && typeof filter.value[0] === 'object' ? filter.value.map((v: any) => v.value || '') : []}
25
+ isRange={filter.multiple}
25
26
  setFilterValues={(filterValues) => {
26
27
  setFilters((prev) =>
27
28
  prev.map((f) =>
28
29
  f === filter ? {
29
30
  ...f,
30
- value: filterValues.length > 0 ? [{
31
- value: filterValues[0],
32
- label: dayjs(filterValues[0]).format("LLL dd, y"),
33
- }] : []
31
+ value: filterValues.length > 0 ?
32
+ filterValues.map(dateValue => ({
33
+ value: dateValue,
34
+ label: dayjs(dateValue).format("LLL dd, y"),
35
+ })) : []
34
36
  } : f
35
37
  )
36
38
  );
@@ -1,5 +1,5 @@
1
1
  export * from './animateChangeInHeight';
2
- export * from './comboBox';
2
+ export * from './comboBox/comboBox';
3
3
  export * from './filterBar';
4
4
  export * from './filters';
5
5
  export * from './types';
@@ -13,6 +13,7 @@ export interface FilterGroup {
13
13
  name: string;
14
14
  placeholder?: string;
15
15
  type?: "select" | "date" | "text" | "stringList";
16
+ multiple?: boolean;
16
17
  options?: FilterGroupOption[];
17
18
  allowCreate?: boolean;
18
19
  filterBy?: (value: string, searchText: string) => boolean;
@@ -24,6 +25,7 @@ export interface Filter {
24
25
  placeholder?: string;
25
26
  value: FilterOption[] | string[];
26
27
  type?: "select" | "date" | "text" | "stringList";
28
+ multiple?: boolean;
27
29
  }
28
30
 
29
31
  export enum FilterOperator {
@@ -1,6 +1,6 @@
1
1
  import { Transition } from "@headlessui/react"
2
2
  import { CircleCheck, AlertTriangle, Info, CircleX, X } from "lucide-react"
3
- import { Fragment, useEffect, useState } from "react"
3
+ import { Fragment, useEffect, useState, useRef } from "react"
4
4
  import { ToastProps } from "./ToastProps.js"
5
5
 
6
6
  const icons = {
@@ -11,10 +11,10 @@ const icons = {
11
11
  }
12
12
 
13
13
  const colors = {
14
- success: 'text-green-600',
15
- error: 'text-red-600',
16
- warning: 'text-yellow-600',
17
- info: 'text-blue-600'
14
+ success: 'text-success',
15
+ error: 'text-destructive',
16
+ warning: 'text-attention',
17
+ info: 'text-info'
18
18
  }
19
19
 
20
20
  interface NotificationPanelProps {
@@ -23,23 +23,31 @@ interface NotificationPanelProps {
23
23
  }
24
24
  export function NotificationPanel({ data, onClose }: NotificationPanelProps) {
25
25
  const [show, setShow] = useState(true)
26
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null)
26
27
 
27
- useEffect(() => {
28
- let timeoutId: any;
28
+ const resetTimeout = () => {
29
+ if (timeoutRef.current) {
30
+ globalThis.clearTimeout(timeoutRef.current)
31
+ }
29
32
  if (data.duration) {
30
- timeoutId = setTimeout(() => {
31
- setShow(false)
32
- }, data.duration);
33
+ timeoutRef.current = setTimeout(() => setShow(false), data.duration)
33
34
  }
34
- return () => {
35
- if (timeoutId) {
36
- clearTimeout(timeoutId);
37
- }
35
+ }
36
+
37
+ const clearCurrentTimeout = () => {
38
+ if (timeoutRef.current) {
39
+ globalThis.clearTimeout(timeoutRef.current)
40
+ timeoutRef.current = null
38
41
  }
39
- }, [])
42
+ }
43
+
44
+ useEffect(() => {
45
+ resetTimeout()
46
+ return clearCurrentTimeout
47
+ }, [data.duration])
40
48
 
41
49
  const Icon = icons[data.status] || Info;
42
- const color = colors[data.status] || 'text-blue-600';
50
+ const color = colors[data.status] || 'text-info';
43
51
 
44
52
  // Global notification live region, render this permanently at the end of the document
45
53
  return (
@@ -61,20 +69,28 @@ export function NotificationPanel({ data, onClose }: NotificationPanelProps) {
61
69
  leaveFrom="opacity-100"
62
70
  leaveTo="opacity-0"
63
71
  >
64
- <div className="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
65
- <div className="p-4">
72
+ <div
73
+ className="pointer-events-auto w-full max-w-md overflow-hidden rounded-lg bg-muted shadow-lg ring-1 ring-border"
74
+ onMouseEnter={clearCurrentTimeout}
75
+ onMouseLeave={resetTimeout}
76
+ >
77
+ <div className="p-5">
66
78
  <div className="flex items-start">
67
79
  <div className="shrink-0">
68
80
  <Icon className={`size-6 ${color}`} aria-hidden="true" />
69
81
  </div>
70
- <div className="ml-3 w-0 flex-1 pt-0.5">
71
- <p className="text-sm font-medium text-gray-900">{data.title}</p>
72
- <p className="mt-1 text-sm text-gray-500">{data.description}</p>
82
+ <div className="ml-3 flex-1 pt-0.5 min-w-0">
83
+ <p className="text-sm font-semibold text-foreground break-words">{data.title}</p>
84
+ {data.description && (
85
+ <p className="mt-2 text-sm text-muted break-words whitespace-pre-wrap leading-relaxed">
86
+ {data.description}
87
+ </p>
88
+ )}
73
89
  </div>
74
90
  <div className="ml-4 flex shrink-0">
75
91
  <button
76
92
  type="button"
77
- className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
93
+ className="inline-flex rounded-md bg-muted text-muted hover:text-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background"
78
94
  onClick={() => setShow(false)}
79
95
  >
80
96
  <span className="sr-only">Close</span>