@vertesia/ui 1.5.0-dev.20260717.131047Z → 1.5.0-dev.20260725.083715Z

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 (567) hide show
  1. package/lib/core/components/SidePanel.js +1 -1
  2. package/lib/core/components/SidePanel.js.map +1 -1
  3. package/lib/core/components/shadcn/button.d.ts +10 -3
  4. package/lib/core/components/shadcn/button.d.ts.map +1 -1
  5. package/lib/core/components/shadcn/button.js +41 -9
  6. package/lib/core/components/shadcn/button.js.map +1 -1
  7. package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  8. package/lib/core/components/shadcn/filters/filterBar.js +1 -1
  9. package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
  10. package/lib/core/components/shadcn/modal/dialog.d.ts +1 -1
  11. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  12. package/lib/core/components/shadcn/modal/dialog.js +3 -1
  13. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  14. package/lib/core/components/shadcn/tabs.d.ts +12 -1
  15. package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
  16. package/lib/core/components/shadcn/tabs.js +12 -4
  17. package/lib/core/components/shadcn/tabs.js.map +1 -1
  18. package/lib/core/components/shadcn/theme/ThemeSwitcher.js +1 -1
  19. package/lib/core/components/shadcn/theme/ThemeSwitcher.js.map +1 -1
  20. package/lib/features/agent/chat/AgentChatPlaybackControls.d.ts.map +1 -1
  21. package/lib/features/agent/chat/AgentChatPlaybackControls.js +2 -2
  22. package/lib/features/agent/chat/AgentChatPlaybackControls.js.map +1 -1
  23. package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
  24. package/lib/features/agent/chat/AgentRequestInputOverlay.js +2 -2
  25. package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
  26. package/lib/features/agent/chat/AgentRightPanel.d.ts +5 -1
  27. package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
  28. package/lib/features/agent/chat/AgentRightPanel.js +2 -2
  29. package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
  30. package/lib/features/agent/chat/ArtifactsTab.d.ts +5 -1
  31. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  32. package/lib/features/agent/chat/ArtifactsTab.js +53 -13
  33. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  34. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts +6 -0
  35. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts.map +1 -0
  36. package/lib/features/agent/chat/DocumentEditingActionCard.js +129 -0
  37. package/lib/features/agent/chat/DocumentEditingActionCard.js.map +1 -0
  38. package/lib/features/agent/chat/ImageLightbox.d.ts.map +1 -1
  39. package/lib/features/agent/chat/ImageLightbox.js +1 -1
  40. package/lib/features/agent/chat/ImageLightbox.js.map +1 -1
  41. package/lib/features/agent/chat/ModernAgentConversation.d.ts +19 -1
  42. package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  43. package/lib/features/agent/chat/ModernAgentConversation.js +125 -27
  44. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  45. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts +45 -0
  46. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -0
  47. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js +40 -0
  48. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -0
  49. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -1
  50. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  51. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +96 -51
  52. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  53. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +2 -1
  54. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
  55. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +9 -5
  56. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
  57. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +25 -0
  58. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -0
  59. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +33 -0
  60. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -0
  61. package/lib/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  62. package/lib/features/agent/chat/ModernAgentOutput/Header.js +4 -2
  63. package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  64. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
  65. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +2 -2
  66. package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
  67. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +3 -1
  68. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  69. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +23 -24
  70. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  71. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts +14 -0
  72. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts.map +1 -0
  73. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js +21 -0
  74. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js.map +1 -0
  75. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts +30 -0
  76. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts.map +1 -0
  77. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +53 -0
  78. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js.map +1 -0
  79. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
  80. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +21 -2
  81. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  82. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +6 -0
  83. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
  84. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +15 -1
  85. package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
  86. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts +6 -0
  87. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts.map +1 -0
  88. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js +29 -0
  89. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js.map +1 -0
  90. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts +33 -0
  91. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts.map +1 -0
  92. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js +129 -0
  93. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js.map +1 -0
  94. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +7 -0
  95. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  96. package/lib/features/agent/chat/ModernAgentOutput/utils.js +11 -1
  97. package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  98. package/lib/features/agent/chat/hooks/useAgentStream.d.ts +1 -1
  99. package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
  100. package/lib/features/agent/chat/hooks/useAgentStream.js +24 -9
  101. package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
  102. package/lib/features/agent/chat/index.d.ts +2 -1
  103. package/lib/features/agent/chat/index.d.ts.map +1 -1
  104. package/lib/features/agent/chat/index.js +3 -0
  105. package/lib/features/agent/chat/index.js.map +1 -1
  106. package/lib/features/environment/SelectEnvironment.d.ts +28 -0
  107. package/lib/features/environment/SelectEnvironment.d.ts.map +1 -0
  108. package/lib/features/environment/SelectEnvironment.js +97 -0
  109. package/lib/features/environment/SelectEnvironment.js.map +1 -0
  110. package/lib/features/environment/index.d.ts +2 -0
  111. package/lib/features/environment/index.d.ts.map +1 -0
  112. package/lib/features/environment/index.js +2 -0
  113. package/lib/features/environment/index.js.map +1 -0
  114. package/lib/features/index.d.ts +2 -0
  115. package/lib/features/index.d.ts.map +1 -1
  116. package/lib/features/index.js +2 -0
  117. package/lib/features/index.js.map +1 -1
  118. package/lib/features/magic-pdf/AnnotatedImageSlider.js +12 -12
  119. package/lib/features/magic-pdf/AnnotatedImageSlider.js.map +1 -1
  120. package/lib/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
  121. package/lib/features/magic-pdf/DownloadPopover.js +3 -17
  122. package/lib/features/magic-pdf/DownloadPopover.js.map +1 -1
  123. package/lib/features/magic-pdf/ExtractedContentView.js +2 -6
  124. package/lib/features/magic-pdf/ExtractedContentView.js.map +1 -1
  125. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts +25 -0
  126. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts.map +1 -0
  127. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js +42 -0
  128. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js.map +1 -0
  129. package/lib/features/magic-pdf/GroundedExtractionView.d.ts +27 -0
  130. package/lib/features/magic-pdf/GroundedExtractionView.d.ts.map +1 -0
  131. package/lib/features/magic-pdf/GroundedExtractionView.js +377 -0
  132. package/lib/features/magic-pdf/GroundedExtractionView.js.map +1 -0
  133. package/lib/features/magic-pdf/MagicPdfProvider.d.ts +0 -2
  134. package/lib/features/magic-pdf/MagicPdfProvider.d.ts.map +1 -1
  135. package/lib/features/magic-pdf/MagicPdfProvider.js +15 -42
  136. package/lib/features/magic-pdf/MagicPdfProvider.js.map +1 -1
  137. package/lib/features/magic-pdf/MagicPdfView.d.ts.map +1 -1
  138. package/lib/features/magic-pdf/MagicPdfView.js +2 -19
  139. package/lib/features/magic-pdf/MagicPdfView.js.map +1 -1
  140. package/lib/features/magic-pdf/index.d.ts +1 -0
  141. package/lib/features/magic-pdf/index.d.ts.map +1 -1
  142. package/lib/features/magic-pdf/index.js +1 -0
  143. package/lib/features/magic-pdf/index.js.map +1 -1
  144. package/lib/features/magic-pdf/types.d.ts +1 -1
  145. package/lib/features/magic-pdf/types.d.ts.map +1 -1
  146. package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -1
  147. package/lib/features/oauth/McpConnectionsButton.js +2 -2
  148. package/lib/features/oauth/McpConnectionsButton.js.map +1 -1
  149. package/lib/features/oauth/McpConnectionsDialog.d.ts.map +1 -1
  150. package/lib/features/oauth/McpConnectionsDialog.js +1 -1
  151. package/lib/features/oauth/McpConnectionsDialog.js.map +1 -1
  152. package/lib/features/oauth/RemoteMcpConnectionButton.d.ts.map +1 -1
  153. package/lib/features/oauth/RemoteMcpConnectionButton.js +1 -1
  154. package/lib/features/oauth/RemoteMcpConnectionButton.js.map +1 -1
  155. package/lib/features/pdf-viewer/PdfPageSlider.js +2 -2
  156. package/lib/features/pdf-viewer/PdfPageSlider.js.map +1 -1
  157. package/lib/features/pdf-viewer/SimplePdfViewer.d.ts.map +1 -1
  158. package/lib/features/pdf-viewer/SimplePdfViewer.js +3 -3
  159. package/lib/features/pdf-viewer/SimplePdfViewer.js.map +1 -1
  160. package/lib/features/permissions/UserPermissionsProvider.js +1 -1
  161. package/lib/features/permissions/UserPermissionsProvider.js.map +1 -1
  162. package/lib/features/store/objects/DocumentQuickFilter.d.ts.map +1 -1
  163. package/lib/features/store/objects/DocumentQuickFilter.js +5 -5
  164. package/lib/features/store/objects/DocumentQuickFilter.js.map +1 -1
  165. package/lib/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  166. package/lib/features/store/objects/DocumentSearchResults.js +4 -4
  167. package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
  168. package/lib/features/store/objects/components/ContentDispositionButton.d.ts.map +1 -1
  169. package/lib/features/store/objects/components/ContentDispositionButton.js +1 -1
  170. package/lib/features/store/objects/components/ContentDispositionButton.js.map +1 -1
  171. package/lib/features/store/objects/components/ContentOverview.d.ts +2 -1
  172. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  173. package/lib/features/store/objects/components/ContentOverview.js +159 -31
  174. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  175. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts +16 -0
  176. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts.map +1 -0
  177. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js +116 -0
  178. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js.map +1 -0
  179. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts +7 -0
  180. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts.map +1 -0
  181. package/lib/features/store/objects/components/DocumentEditingLockStatus.js +13 -0
  182. package/lib/features/store/objects/components/DocumentEditingLockStatus.js.map +1 -0
  183. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts +48 -0
  184. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts.map +1 -0
  185. package/lib/features/store/objects/components/DocumentEditingPanel.js +720 -0
  186. package/lib/features/store/objects/components/DocumentEditingPanel.js.map +1 -0
  187. package/lib/features/store/objects/components/DocumentIcon.js +1 -1
  188. package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
  189. package/lib/features/store/objects/components/TextEditorPanel.js +22 -9
  190. package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
  191. package/lib/features/store/objects/components/VectorSearchWidget.js +1 -1
  192. package/lib/features/store/objects/components/VectorSearchWidget.js.map +1 -1
  193. package/lib/features/store/objects/components/documentArtifactRefs.d.ts +26 -0
  194. package/lib/features/store/objects/components/documentArtifactRefs.d.ts.map +1 -0
  195. package/lib/features/store/objects/components/documentArtifactRefs.js +52 -0
  196. package/lib/features/store/objects/components/documentArtifactRefs.js.map +1 -0
  197. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts +4 -0
  198. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts.map +1 -0
  199. package/lib/features/store/objects/components/documentEditingAgentConfig.js +40 -0
  200. package/lib/features/store/objects/components/documentEditingAgentConfig.js.map +1 -0
  201. package/lib/features/store/objects/components/documentEditingPrompts.d.ts +3 -0
  202. package/lib/features/store/objects/components/documentEditingPrompts.d.ts.map +1 -0
  203. package/lib/features/store/objects/components/documentEditingPrompts.js +13 -0
  204. package/lib/features/store/objects/components/documentEditingPrompts.js.map +1 -0
  205. package/lib/features/store/objects/components/documentEditingRun.d.ts +27 -0
  206. package/lib/features/store/objects/components/documentEditingRun.d.ts.map +1 -0
  207. package/lib/features/store/objects/components/documentEditingRun.js +126 -0
  208. package/lib/features/store/objects/components/documentEditingRun.js.map +1 -0
  209. package/lib/features/store/objects/components/documentEditingTarget.d.ts +20 -0
  210. package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -0
  211. package/lib/features/store/objects/components/documentEditingTarget.js +40 -0
  212. package/lib/features/store/objects/components/documentEditingTarget.js.map +1 -0
  213. package/lib/features/store/objects/components/index.d.ts +1 -0
  214. package/lib/features/store/objects/components/index.d.ts.map +1 -1
  215. package/lib/features/store/objects/components/index.js +1 -0
  216. package/lib/features/store/objects/components/index.js.map +1 -1
  217. package/lib/features/store/objects/components/useContentPanelHooks.d.ts +6 -3
  218. package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
  219. package/lib/features/store/objects/components/useContentPanelHooks.js +57 -37
  220. package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
  221. package/lib/features/store/objects/components/useDownloadFile.d.ts +2 -1
  222. package/lib/features/store/objects/components/useDownloadFile.d.ts.map +1 -1
  223. package/lib/features/store/objects/components/useDownloadFile.js +3 -0
  224. package/lib/features/store/objects/components/useDownloadFile.js.map +1 -1
  225. package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
  226. package/lib/features/store/objects/layout/renderers.js +2 -2
  227. package/lib/features/store/objects/layout/renderers.js.map +1 -1
  228. package/lib/features/store/objects/selection/SelectionActions.js +1 -1
  229. package/lib/features/store/objects/selection/SelectionActions.js.map +1 -1
  230. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
  231. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js.map +1 -1
  232. package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
  233. package/lib/features/store/types/ContentObjectTypesTable.js +4 -4
  234. package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
  235. package/lib/features/store/types/IntakePolicyEditor.d.ts +15 -0
  236. package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -0
  237. package/lib/features/store/types/IntakePolicyEditor.js +455 -0
  238. package/lib/features/store/types/IntakePolicyEditor.js.map +1 -0
  239. package/lib/features/store/types/IntakePolicyForm.d.ts +11 -0
  240. package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -0
  241. package/lib/features/store/types/IntakePolicyForm.js +91 -0
  242. package/lib/features/store/types/IntakePolicyForm.js.map +1 -0
  243. package/lib/features/store/types/SelectContentTypeModal.js +1 -1
  244. package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
  245. package/lib/features/store/types/index.d.ts +2 -0
  246. package/lib/features/store/types/index.d.ts.map +1 -1
  247. package/lib/features/store/types/index.js +2 -0
  248. package/lib/features/store/types/index.js.map +1 -1
  249. package/lib/features/store/types/intake-policy-editor.logic.d.ts +7 -0
  250. package/lib/features/store/types/intake-policy-editor.logic.d.ts.map +1 -0
  251. package/lib/features/store/types/intake-policy-editor.logic.js +60 -0
  252. package/lib/features/store/types/intake-policy-editor.logic.js.map +1 -0
  253. package/lib/features/store/types/typeCatalogCache.d.ts +5 -0
  254. package/lib/features/store/types/typeCatalogCache.d.ts.map +1 -0
  255. package/lib/features/store/types/typeCatalogCache.js +40 -0
  256. package/lib/features/store/types/typeCatalogCache.js.map +1 -0
  257. package/lib/features/user/UserInfo.js +7 -3
  258. package/lib/features/user/UserInfo.js.map +1 -1
  259. package/lib/features/views/ViewExperience.d.ts +20 -0
  260. package/lib/features/views/ViewExperience.d.ts.map +1 -0
  261. package/lib/features/views/ViewExperience.js +188 -0
  262. package/lib/features/views/ViewExperience.js.map +1 -0
  263. package/lib/features/views/ViewNavigation.d.ts +3 -0
  264. package/lib/features/views/ViewNavigation.d.ts.map +1 -0
  265. package/lib/features/views/ViewNavigation.js +36 -0
  266. package/lib/features/views/ViewNavigation.js.map +1 -0
  267. package/lib/features/views/ViewResults.d.ts +9 -0
  268. package/lib/features/views/ViewResults.d.ts.map +1 -0
  269. package/lib/features/views/ViewResults.js +229 -0
  270. package/lib/features/views/ViewResults.js.map +1 -0
  271. package/lib/features/views/ViewSearch.d.ts +3 -0
  272. package/lib/features/views/ViewSearch.d.ts.map +1 -0
  273. package/lib/features/views/ViewSearch.js +74 -0
  274. package/lib/features/views/ViewSearch.js.map +1 -0
  275. package/lib/features/views/index.d.ts +7 -0
  276. package/lib/features/views/index.d.ts.map +1 -0
  277. package/lib/features/views/index.js +7 -0
  278. package/lib/features/views/index.js.map +1 -0
  279. package/lib/features/views/types.d.ts +39 -0
  280. package/lib/features/views/types.d.ts.map +1 -0
  281. package/lib/features/views/types.js +2 -0
  282. package/lib/features/views/types.js.map +1 -0
  283. package/lib/features/views/viewState.d.ts +14 -0
  284. package/lib/features/views/viewState.d.ts.map +1 -0
  285. package/lib/features/views/viewState.js +117 -0
  286. package/lib/features/views/viewState.js.map +1 -0
  287. package/lib/i18n/locales/ar.json +134 -1
  288. package/lib/i18n/locales/de.json +130 -1
  289. package/lib/i18n/locales/en.json +363 -33
  290. package/lib/i18n/locales/es.json +131 -1
  291. package/lib/i18n/locales/fr.json +131 -1
  292. package/lib/i18n/locales/it.json +131 -1
  293. package/lib/i18n/locales/ja.json +129 -1
  294. package/lib/i18n/locales/ko.json +129 -1
  295. package/lib/i18n/locales/pt.json +131 -1
  296. package/lib/i18n/locales/ru.json +132 -1
  297. package/lib/i18n/locales/tr.json +130 -1
  298. package/lib/i18n/locales/zh-TW.json +129 -1
  299. package/lib/i18n/locales/zh.json +129 -1
  300. package/lib/rich-text/EditorToolbar.d.ts +37 -0
  301. package/lib/rich-text/EditorToolbar.d.ts.map +1 -0
  302. package/lib/rich-text/EditorToolbar.js +215 -0
  303. package/lib/rich-text/EditorToolbar.js.map +1 -0
  304. package/lib/rich-text/VertesiaRichTextEditor.d.ts +26 -0
  305. package/lib/rich-text/VertesiaRichTextEditor.d.ts.map +1 -0
  306. package/lib/rich-text/VertesiaRichTextEditor.js +67 -0
  307. package/lib/rich-text/VertesiaRichTextEditor.js.map +1 -0
  308. package/lib/rich-text/index.d.ts +2 -0
  309. package/lib/rich-text/index.d.ts.map +1 -0
  310. package/lib/rich-text/index.js +2 -0
  311. package/lib/rich-text/index.js.map +1 -0
  312. package/lib/router/HistoryNavigator.d.ts.map +1 -1
  313. package/lib/router/HistoryNavigator.js +23 -13
  314. package/lib/router/HistoryNavigator.js.map +1 -1
  315. package/lib/router/Nav.d.ts.map +1 -1
  316. package/lib/router/Nav.js +15 -6
  317. package/lib/router/Nav.js.map +1 -1
  318. package/lib/session/UserSession.d.ts.map +1 -1
  319. package/lib/session/UserSession.js +5 -3
  320. package/lib/session/UserSession.js.map +1 -1
  321. package/lib/vertesia-ui-core.js +4 -4
  322. package/lib/vertesia-ui-core.js.map +1 -1
  323. package/lib/vertesia-ui-features.js +40 -28
  324. package/lib/vertesia-ui-features.js.map +1 -1
  325. package/lib/vertesia-ui-i18n.js +15 -15
  326. package/lib/vertesia-ui-i18n.js.map +1 -1
  327. package/lib/vertesia-ui-rich-text.js +5 -0
  328. package/lib/vertesia-ui-rich-text.js.map +1 -0
  329. package/lib/vertesia-ui-router.js +1 -1
  330. package/lib/vertesia-ui-router.js.map +1 -1
  331. package/lib/vertesia-ui-session.js +1 -1
  332. package/lib/vertesia-ui-session.js.map +1 -1
  333. package/lib/vertesia-ui-shell.js +1 -1
  334. package/lib/vertesia-ui-shell.js.map +1 -1
  335. package/lib/vertesia-ui-widgets.js +25 -7
  336. package/lib/vertesia-ui-widgets.js.map +1 -1
  337. package/lib/widgets/form/Form.js +1 -1
  338. package/lib/widgets/form/Form.js.map +1 -1
  339. package/lib/widgets/json-view/JSONSwitcher.js +1 -1
  340. package/lib/widgets/json-view/JSONSwitcher.js.map +1 -1
  341. package/lib/widgets/json-view/JSONView.js +6 -6
  342. package/lib/widgets/json-view/JSONView.js.map +1 -1
  343. package/lib/widgets/markdown/AgentResourceResolver.d.ts +31 -0
  344. package/lib/widgets/markdown/AgentResourceResolver.d.ts.map +1 -0
  345. package/lib/widgets/markdown/AgentResourceResolver.js +39 -0
  346. package/lib/widgets/markdown/AgentResourceResolver.js.map +1 -0
  347. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts +63 -0
  348. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts.map +1 -0
  349. package/lib/widgets/markdown/ArtifactEditingSurface.js +582 -0
  350. package/lib/widgets/markdown/ArtifactEditingSurface.js.map +1 -0
  351. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts +69 -0
  352. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts.map +1 -0
  353. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +374 -0
  354. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js.map +1 -0
  355. package/lib/widgets/markdown/MarkdownLink.d.ts +3 -1
  356. package/lib/widgets/markdown/MarkdownLink.d.ts.map +1 -1
  357. package/lib/widgets/markdown/MarkdownLink.js +41 -14
  358. package/lib/widgets/markdown/MarkdownLink.js.map +1 -1
  359. package/lib/widgets/markdown/MarkdownRenderer.d.ts +8 -1
  360. package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  361. package/lib/widgets/markdown/MarkdownRenderer.js +20 -4
  362. package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
  363. package/lib/widgets/markdown/index.d.ts +5 -1
  364. package/lib/widgets/markdown/index.d.ts.map +1 -1
  365. package/lib/widgets/markdown/index.js +5 -1
  366. package/lib/widgets/markdown/index.js.map +1 -1
  367. package/lib/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -1
  368. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js +14 -2
  369. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -1
  370. package/lib/widgets/markdown/textDiff.d.ts +52 -0
  371. package/lib/widgets/markdown/textDiff.d.ts.map +1 -0
  372. package/lib/widgets/markdown/textDiff.js +362 -0
  373. package/lib/widgets/markdown/textDiff.js.map +1 -0
  374. package/lib/widgets/markdown/useArtifactContent.d.ts +5 -3
  375. package/lib/widgets/markdown/useArtifactContent.d.ts.map +1 -1
  376. package/lib/widgets/markdown/useArtifactContent.js +6 -3
  377. package/lib/widgets/markdown/useArtifactContent.js.map +1 -1
  378. package/lib/widgets/markdown/useResolvedUrl.d.ts +1 -5
  379. package/lib/widgets/markdown/useResolvedUrl.d.ts.map +1 -1
  380. package/lib/widgets/markdown/useResolvedUrl.js +19 -31
  381. package/lib/widgets/markdown/useResolvedUrl.js.map +1 -1
  382. package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  383. package/lib/widgets/monacoEditor/MonacoEditor.js +29 -0
  384. package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  385. package/lib/widgets/schema-editor/ManagedSchema.d.ts +8 -0
  386. package/lib/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
  387. package/lib/widgets/schema-editor/ManagedSchema.js +16 -0
  388. package/lib/widgets/schema-editor/ManagedSchema.js.map +1 -1
  389. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.d.ts +2 -0
  390. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.d.ts.map +1 -1
  391. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.js +1 -0
  392. package/lib/widgets/schema-editor/editor/EditableSchemaProperty.js.map +1 -1
  393. package/lib/widgets/schema-editor/editor/PropertyViewer.d.ts.map +1 -1
  394. package/lib/widgets/schema-editor/editor/PropertyViewer.js +4 -1
  395. package/lib/widgets/schema-editor/editor/PropertyViewer.js.map +1 -1
  396. package/lib/widgets/schema-editor/editor/SchemaEditor.d.ts.map +1 -1
  397. package/lib/widgets/schema-editor/editor/SchemaEditor.js +22 -11
  398. package/lib/widgets/schema-editor/editor/SchemaEditor.js.map +1 -1
  399. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +9 -0
  400. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
  401. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +20 -17
  402. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
  403. package/package.json +37 -33
  404. package/src/__tests__/a11y.test.tsx +77 -1
  405. package/src/__tests__/axe-helper.ts +17 -7
  406. package/src/__tests__/setup.ts +25 -0
  407. package/src/core/components/SidePanel.tsx +1 -1
  408. package/src/core/components/shadcn/button.tsx +67 -12
  409. package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
  410. package/src/core/components/shadcn/modal/dialog.tsx +4 -2
  411. package/src/core/components/shadcn/tabs.test.tsx +65 -0
  412. package/src/core/components/shadcn/tabs.tsx +25 -3
  413. package/src/core/components/shadcn/theme/ThemeSwitcher.tsx +1 -1
  414. package/src/features/agent/chat/AgentChatPlaybackControls.tsx +0 -5
  415. package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +31 -0
  416. package/src/features/agent/chat/AgentRequestInputOverlay.tsx +6 -2
  417. package/src/features/agent/chat/AgentRightPanel.tsx +16 -1
  418. package/src/features/agent/chat/ArtifactsTab.test.tsx +55 -0
  419. package/src/features/agent/chat/ArtifactsTab.tsx +222 -61
  420. package/src/features/agent/chat/DocumentEditingActionCard.test.tsx +105 -0
  421. package/src/features/agent/chat/DocumentEditingActionCard.tsx +210 -0
  422. package/src/features/agent/chat/ImageLightbox.tsx +0 -1
  423. package/src/features/agent/chat/ModernAgentConversation.test.tsx +285 -40
  424. package/src/features/agent/chat/ModernAgentConversation.tsx +247 -77
  425. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.test.tsx +79 -0
  426. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.tsx +94 -0
  427. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +263 -35
  428. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +236 -118
  429. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +17 -0
  430. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.test.tsx +44 -0
  431. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +88 -0
  432. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +3 -3
  433. package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +0 -2
  434. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +34 -47
  435. package/src/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.tsx +40 -0
  436. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.test.tsx +148 -0
  437. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.tsx +141 -0
  438. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +33 -1
  439. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +80 -0
  440. package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +21 -1
  441. package/src/features/agent/chat/ModernAgentOutput/resourceLinks.tsx +43 -0
  442. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.test.ts +229 -0
  443. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.ts +152 -0
  444. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +17 -0
  445. package/src/features/agent/chat/ModernAgentOutput/utils.ts +14 -1
  446. package/src/features/agent/chat/hooks/useAgentStream.test.tsx +188 -0
  447. package/src/features/agent/chat/hooks/useAgentStream.ts +28 -8
  448. package/src/features/agent/chat/index.ts +11 -0
  449. package/src/features/environment/SelectEnvironment.tsx +186 -0
  450. package/src/features/environment/index.ts +1 -0
  451. package/src/features/index.ts +2 -0
  452. package/src/features/magic-pdf/AnnotatedImageSlider.tsx +62 -66
  453. package/src/features/magic-pdf/DownloadPopover.tsx +5 -48
  454. package/src/features/magic-pdf/ExtractedContentView.tsx +2 -14
  455. package/src/features/magic-pdf/GroundedExtractionAssistantPanel.tsx +86 -0
  456. package/src/features/magic-pdf/GroundedExtractionView.test.tsx +65 -0
  457. package/src/features/magic-pdf/GroundedExtractionView.tsx +1055 -0
  458. package/src/features/magic-pdf/MagicPdfProvider.tsx +17 -47
  459. package/src/features/magic-pdf/MagicPdfView.tsx +3 -51
  460. package/src/features/magic-pdf/index.ts +1 -0
  461. package/src/features/magic-pdf/types.ts +1 -1
  462. package/src/features/oauth/McpConnectionsButton.tsx +0 -2
  463. package/src/features/oauth/McpConnectionsDialog.tsx +0 -1
  464. package/src/features/oauth/RemoteMcpConnectionButton.tsx +0 -1
  465. package/src/features/pdf-viewer/PdfPageSlider.tsx +5 -5
  466. package/src/features/pdf-viewer/SimplePdfViewer.tsx +11 -12
  467. package/src/features/permissions/UserPermissionsProvider.tsx +1 -1
  468. package/src/features/store/objects/DocumentQuickFilter.tsx +13 -15
  469. package/src/features/store/objects/DocumentSearchResults.tsx +5 -8
  470. package/src/features/store/objects/components/ContentDispositionButton.tsx +5 -1
  471. package/src/features/store/objects/components/ContentOverview.tsx +356 -105
  472. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.test.ts +34 -0
  473. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.tsx +211 -0
  474. package/src/features/store/objects/components/DocumentEditingLockStatus.test.tsx +32 -0
  475. package/src/features/store/objects/components/DocumentEditingLockStatus.tsx +45 -0
  476. package/src/features/store/objects/components/DocumentEditingPanel.test.tsx +336 -0
  477. package/src/features/store/objects/components/DocumentEditingPanel.tsx +1236 -0
  478. package/src/features/store/objects/components/DocumentIcon.tsx +1 -1
  479. package/src/features/store/objects/components/TextEditorPanel.test.tsx +48 -0
  480. package/src/features/store/objects/components/TextEditorPanel.tsx +41 -20
  481. package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
  482. package/src/features/store/objects/components/documentArtifactRefs.test.ts +65 -0
  483. package/src/features/store/objects/components/documentArtifactRefs.ts +72 -0
  484. package/src/features/store/objects/components/documentEditingAgentConfig.test.ts +28 -0
  485. package/src/features/store/objects/components/documentEditingAgentConfig.ts +41 -0
  486. package/src/features/store/objects/components/documentEditingPrompts.test.ts +26 -0
  487. package/src/features/store/objects/components/documentEditingPrompts.ts +12 -0
  488. package/src/features/store/objects/components/documentEditingRun.test.ts +176 -0
  489. package/src/features/store/objects/components/documentEditingRun.ts +184 -0
  490. package/src/features/store/objects/components/documentEditingTarget.test.ts +96 -0
  491. package/src/features/store/objects/components/documentEditingTarget.ts +63 -0
  492. package/src/features/store/objects/components/index.ts +1 -0
  493. package/src/features/store/objects/components/useContentPanelHooks.ts +55 -42
  494. package/src/features/store/objects/components/useDownloadFile.test.ts +20 -0
  495. package/src/features/store/objects/components/useDownloadFile.ts +5 -1
  496. package/src/features/store/objects/layout/renderers.tsx +1 -2
  497. package/src/features/store/objects/selection/SelectionActions.tsx +1 -1
  498. package/src/features/store/objects/selection/actions/StartWorkflowButton.tsx +2 -2
  499. package/src/features/store/types/ContentObjectTypesTable.tsx +12 -14
  500. package/src/features/store/types/IntakePolicyEditor.tsx +679 -0
  501. package/src/features/store/types/IntakePolicyForm.tsx +838 -0
  502. package/src/features/store/types/SelectContentTypeModal.tsx +2 -2
  503. package/src/features/store/types/index.ts +2 -0
  504. package/src/features/store/types/intake-policy-editor.logic.test.ts +109 -0
  505. package/src/features/store/types/intake-policy-editor.logic.ts +87 -0
  506. package/src/features/store/types/typeCatalogCache.ts +45 -0
  507. package/src/features/user/UserInfo.tsx +7 -7
  508. package/src/features/views/ViewExperience.test.tsx +273 -0
  509. package/src/features/views/ViewExperience.tsx +408 -0
  510. package/src/features/views/ViewNavigation.test.tsx +86 -0
  511. package/src/features/views/ViewNavigation.tsx +187 -0
  512. package/src/features/views/ViewResults.test.ts +82 -0
  513. package/src/features/views/ViewResults.tsx +609 -0
  514. package/src/features/views/ViewSearch.test.tsx +147 -0
  515. package/src/features/views/ViewSearch.tsx +205 -0
  516. package/src/features/views/index.ts +6 -0
  517. package/src/features/views/types.ts +57 -0
  518. package/src/features/views/viewState.test.ts +111 -0
  519. package/src/features/views/viewState.ts +132 -0
  520. package/src/i18n/locales/ar.json +134 -1
  521. package/src/i18n/locales/de.json +130 -1
  522. package/src/i18n/locales/en.json +1083 -753
  523. package/src/i18n/locales/es.json +131 -1
  524. package/src/i18n/locales/fr.json +131 -1
  525. package/src/i18n/locales/it.json +131 -1
  526. package/src/i18n/locales/ja.json +129 -1
  527. package/src/i18n/locales/ko.json +129 -1
  528. package/src/i18n/locales/pt.json +131 -1
  529. package/src/i18n/locales/ru.json +132 -1
  530. package/src/i18n/locales/tr.json +130 -1
  531. package/src/i18n/locales/zh-TW.json +129 -1
  532. package/src/i18n/locales/zh.json +129 -1
  533. package/src/rich-text/EditorToolbar.tsx +708 -0
  534. package/src/rich-text/VertesiaRichTextEditor.test.tsx +211 -0
  535. package/src/rich-text/VertesiaRichTextEditor.tsx +241 -0
  536. package/src/rich-text/index.ts +9 -0
  537. package/src/router/HistoryNavigator.test.ts +48 -0
  538. package/src/router/HistoryNavigator.ts +24 -13
  539. package/src/router/Nav.tsx +18 -8
  540. package/src/session/UserSession.test.ts +39 -0
  541. package/src/session/UserSession.ts +5 -3
  542. package/src/widgets/form/Form.tsx +1 -1
  543. package/src/widgets/json-view/JSONSwitcher.tsx +2 -2
  544. package/src/widgets/json-view/JSONView.tsx +7 -7
  545. package/src/widgets/markdown/AgentResourceResolver.test.ts +24 -0
  546. package/src/widgets/markdown/AgentResourceResolver.tsx +70 -0
  547. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +537 -0
  548. package/src/widgets/markdown/ArtifactEditingSurface.tsx +878 -0
  549. package/src/widgets/markdown/CollaborativeMarkdownRenderer.test.tsx +484 -0
  550. package/src/widgets/markdown/CollaborativeMarkdownRenderer.tsx +825 -0
  551. package/src/widgets/markdown/MarkdownLink.test.tsx +122 -0
  552. package/src/widgets/markdown/MarkdownLink.tsx +102 -17
  553. package/src/widgets/markdown/MarkdownRenderer.tsx +30 -3
  554. package/src/widgets/markdown/index.ts +39 -1
  555. package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +15 -2
  556. package/src/widgets/markdown/textDiff.test.ts +156 -0
  557. package/src/widgets/markdown/textDiff.ts +399 -0
  558. package/src/widgets/markdown/useArtifactContent.ts +9 -3
  559. package/src/widgets/markdown/useResolvedUrl.test.ts +29 -40
  560. package/src/widgets/markdown/useResolvedUrl.ts +33 -35
  561. package/src/widgets/monacoEditor/MonacoEditor.tsx +29 -0
  562. package/src/widgets/schema-editor/ManagedSchema.ts +22 -0
  563. package/src/widgets/schema-editor/editor/EditableSchemaProperty.tsx +3 -0
  564. package/src/widgets/schema-editor/editor/PropertyViewer.tsx +14 -3
  565. package/src/widgets/schema-editor/editor/SchemaEditor.tsx +80 -29
  566. package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +26 -0
  567. package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +23 -18
@@ -0,0 +1,408 @@
1
+ import type {
2
+ ExecuteViewRequest,
3
+ ViewDisplayConfiguration,
4
+ ViewExecutionResult,
5
+ ViewHit,
6
+ ViewNavigationItem,
7
+ ViewResultMedia,
8
+ } from '@vertesia/common';
9
+ import { ImageRenditionFormat } from '@vertesia/common';
10
+ import { Button, ErrorBox, MessageBox, SelectBox, Spinner } from '@vertesia/ui/core';
11
+ import { useUITranslation } from '@vertesia/ui/i18n';
12
+ import { FullHeightLayout } from '@vertesia/ui/layout';
13
+ import { useUserSession } from '@vertesia/ui/session';
14
+ import { ChevronLeft, ChevronRight } from 'lucide-react';
15
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
16
+ import { GenericPageNavHeader } from '../layout/GenericPageNavHeader.js';
17
+ import type { ViewExecutor, ViewExperienceRenderers, ViewMediaResolver } from './types.js';
18
+ import { DefaultViewNavigation } from './ViewNavigation.js';
19
+ import { DefaultViewResults } from './ViewResults.js';
20
+ import { DefaultViewSearch } from './ViewSearch.js';
21
+ import { canonicalizeViewState, parseViewState, replaceViewStateInUrl, resolveViewSort } from './viewState.js';
22
+
23
+ const FALLBACK_DISPLAY: ViewDisplayConfiguration = {
24
+ id: 'default',
25
+ label: 'Results',
26
+ type: 'list',
27
+ title: { field: 'name' },
28
+ subtitle: [
29
+ { field: 'type.name', format: 'content_type' },
30
+ { field: 'location', format: 'location' },
31
+ ],
32
+ description: { field: 'description' },
33
+ };
34
+
35
+ export interface ViewExperienceProps {
36
+ viewId: string;
37
+ /** Override execution for embedded apps or tests. Defaults to client.views.execute. */
38
+ execute?: ViewExecutor;
39
+ renderers?: ViewExperienceRenderers;
40
+ onOpenHit?: (hit: ViewHit) => void;
41
+ /** Override media resolution for embedded apps or custom storage backends. */
42
+ resolveMedia?: ViewMediaResolver;
43
+ syncUrl?: boolean;
44
+ showHeader?: boolean;
45
+ className?: string;
46
+ }
47
+
48
+ function initialRequest(syncUrl: boolean): ExecuteViewRequest {
49
+ if (!syncUrl || typeof window === 'undefined') return {};
50
+ return parseViewState(window.location.search);
51
+ }
52
+
53
+ function cleanRecord(values: Record<string, string[]>): Record<string, string[]> | undefined {
54
+ const filtered = Object.fromEntries(Object.entries(values).filter(([, entries]) => entries.length > 0));
55
+ return Object.keys(filtered).length > 0 ? filtered : undefined;
56
+ }
57
+
58
+ function ViewExperienceWithSession(props: Omit<ViewExperienceProps, 'execute'>) {
59
+ const { client } = useUserSession();
60
+ const execute = useCallback(
61
+ (request: ExecuteViewRequest) => client.views.execute(props.viewId, request),
62
+ [client, props.viewId],
63
+ );
64
+ const resolveMedia = useCallback<ViewMediaResolver>(
65
+ async (hit: ViewHit, media: ViewResultMedia) => {
66
+ if (media.source !== 'content_thumbnail') return undefined;
67
+
68
+ const content = hit.document.content;
69
+ try {
70
+ const rendition = await client.objects.getRenditionSafe(hit.id, content?.type, {
71
+ format: ImageRenditionFormat.jpeg,
72
+ max_hw: 512,
73
+ generate_if_missing: false,
74
+ sign_url: true,
75
+ });
76
+ if (rendition?.status === 'found' && rendition.renditions?.length) {
77
+ return rendition.renditions[0];
78
+ }
79
+ } catch {
80
+ // A missing optional rendition falls through to the original image.
81
+ }
82
+
83
+ if (content?.source && content.type?.startsWith('image/')) {
84
+ const download = await client.files.getDownloadUrl(content.source);
85
+ return download.url;
86
+ }
87
+ return undefined;
88
+ },
89
+ [client],
90
+ );
91
+ return <ViewExperienceRuntime {...props} execute={execute} resolveMedia={props.resolveMedia ?? resolveMedia} />;
92
+ }
93
+
94
+ /**
95
+ * Reusable renderer for stored and app-contributed View Experiences.
96
+ * Pass `execute` to use it outside Vertesia's session provider.
97
+ */
98
+ export function ViewExperience({ execute, ...props }: ViewExperienceProps) {
99
+ return execute ? (
100
+ <ViewExperienceRuntime key={props.viewId} {...props} execute={execute} />
101
+ ) : (
102
+ <ViewExperienceWithSession key={props.viewId} {...props} />
103
+ );
104
+ }
105
+
106
+ interface ViewExperienceRuntimeProps extends Omit<ViewExperienceProps, 'execute'> {
107
+ execute: ViewExecutor;
108
+ }
109
+
110
+ function ViewExperienceRuntime({
111
+ execute,
112
+ renderers,
113
+ onOpenHit,
114
+ resolveMedia,
115
+ syncUrl = true,
116
+ showHeader = true,
117
+ className,
118
+ }: ViewExperienceRuntimeProps) {
119
+ const { t } = useUITranslation();
120
+ const executeRef = useRef(execute);
121
+ executeRef.current = execute;
122
+ const generationRef = useRef(0);
123
+ const [request, setRequest] = useState<ExecuteViewRequest>(() => initialRequest(syncUrl));
124
+ const [draftQuery, setDraftQuery] = useState(request.query ?? '');
125
+ const [draftKeyTerms, setDraftKeyTerms] = useState<Record<string, string[]>>(request.key_terms ?? {});
126
+ const [result, setResult] = useState<ViewExecutionResult>();
127
+ const [isLoading, setIsLoading] = useState(true);
128
+ const [error, setError] = useState<Error>();
129
+
130
+ const runRequest = useCallback(
131
+ (next: ExecuteViewRequest, updateUrl: boolean) => {
132
+ const generation = ++generationRef.current;
133
+ setRequest(next);
134
+ if (updateUrl && syncUrl) replaceViewStateInUrl(next);
135
+ setIsLoading(true);
136
+ setError(undefined);
137
+ return executeRef
138
+ .current(next)
139
+ .then((response) => {
140
+ if (generation === generationRef.current) {
141
+ const canonicalRequest = canonicalizeViewState(next, response);
142
+ setRequest(canonicalRequest);
143
+ if (syncUrl) replaceViewStateInUrl(canonicalRequest);
144
+ setResult(response);
145
+ }
146
+ })
147
+ .catch((cause: unknown) => {
148
+ if (generation === generationRef.current) {
149
+ setError(cause instanceof Error ? cause : new Error(String(cause)));
150
+ }
151
+ })
152
+ .finally(() => {
153
+ if (generation === generationRef.current) setIsLoading(false);
154
+ });
155
+ },
156
+ [syncUrl],
157
+ );
158
+
159
+ const loadUrlState = useCallback(() => {
160
+ const next = initialRequest(syncUrl);
161
+ setDraftQuery(next.query ?? '');
162
+ setDraftKeyTerms(next.key_terms ?? {});
163
+ return runRequest(next, false);
164
+ }, [runRequest, syncUrl]);
165
+
166
+ useEffect(() => {
167
+ void loadUrlState();
168
+ return () => {
169
+ generationRef.current += 1;
170
+ };
171
+ }, [loadUrlState]);
172
+
173
+ useEffect(() => {
174
+ if (!syncUrl || typeof window === 'undefined') return;
175
+ const onPopState = () => void loadUrlState();
176
+ window.addEventListener('popstate', onPopState);
177
+ return () => window.removeEventListener('popstate', onPopState);
178
+ }, [loadUrlState, syncUrl]);
179
+
180
+ const definition = result?.definition;
181
+ const navigation = useMemo(
182
+ () => [...(definition?.navigation ?? [])].sort((left, right) => (left.order ?? 0) - (right.order ?? 0)),
183
+ [definition?.navigation],
184
+ );
185
+ const resultsConfiguration = definition?.results;
186
+ const effectiveDisplayId = result?.display ?? request.display ?? resultsConfiguration?.default_display;
187
+ const display =
188
+ resultsConfiguration?.displays.find((candidate) => candidate.id === effectiveDisplayId) ?? FALLBACK_DISPLAY;
189
+ const effectiveSortId = result
190
+ ? resolveViewSort(request, result, resultsConfiguration?.default_sort)
191
+ : request.sort;
192
+
193
+ const applyRequest = (next: ExecuteViewRequest) => {
194
+ void runRequest(next, true);
195
+ };
196
+
197
+ const updateNavigation = (item: ViewNavigationItem, values: string[]) => {
198
+ const nextNavigation = cleanRecord({ ...(request.navigation ?? {}), [item.id]: values });
199
+ applyRequest({ ...request, navigation: nextNavigation, offset: undefined });
200
+ };
201
+
202
+ const submitSearch = () => {
203
+ applyRequest({
204
+ ...request,
205
+ query: draftQuery.trim() || undefined,
206
+ key_terms: cleanRecord(draftKeyTerms),
207
+ offset: undefined,
208
+ });
209
+ };
210
+
211
+ if (!result && isLoading) {
212
+ return (
213
+ <div className="flex h-full min-h-48 items-center justify-center">
214
+ <Spinner size="xl" />
215
+ </div>
216
+ );
217
+ }
218
+
219
+ if (!result || !definition) {
220
+ return (
221
+ <div className="flex h-full min-h-48 items-center justify-center p-4">
222
+ <ErrorBox
223
+ title={t('store.searchFailed')}
224
+ action={() => void loadUrlState()}
225
+ actionLabel={t('agent.retry')}
226
+ >
227
+ {t('store.searchFailed')}
228
+ </ErrorBox>
229
+ </div>
230
+ );
231
+ }
232
+
233
+ const SearchRenderer = definition.search?.renderer
234
+ ? (renderers?.search?.[definition.search.renderer] ?? DefaultViewSearch)
235
+ : DefaultViewSearch;
236
+ const ResultsRenderer = display.renderer
237
+ ? (renderers?.results?.[display.renderer] ?? DefaultViewResults)
238
+ : DefaultViewResults;
239
+ const hasSidebarNavigation = navigation.length > 0 && definition.layout?.navigation_position !== 'top';
240
+ const isWorklist = definition.layout?.mode === 'worklist';
241
+ const offset = request.offset ?? 0;
242
+ const pageStep = request.limit ?? display.page_size ?? 20;
243
+ const hasPrevious = offset > 0;
244
+ const hasNext = offset + result.hits.length < result.total;
245
+
246
+ const navigationWidgets = navigation.map((item) => {
247
+ const navigationResult = result.navigation[item.id] ?? { id: item.id, selected: [], nodes: [] };
248
+ const NavigationRenderer = item.renderer
249
+ ? (renderers?.navigation?.[item.renderer] ?? DefaultViewNavigation)
250
+ : DefaultViewNavigation;
251
+ return (
252
+ <NavigationRenderer
253
+ key={item.id}
254
+ configuration={item}
255
+ result={navigationResult}
256
+ isLoading={isLoading}
257
+ onChange={(values) => updateNavigation(item, values)}
258
+ />
259
+ );
260
+ });
261
+
262
+ return (
263
+ <FullHeightLayout className={className}>
264
+ {showHeader && <GenericPageNavHeader title={definition.name} description={definition.description} />}
265
+ <FullHeightLayout.Fixed heightClass="h-auto" className="space-y-3 border-b p-3">
266
+ {definition.search && (
267
+ <SearchRenderer
268
+ configuration={definition.search}
269
+ query={draftQuery}
270
+ keyTerms={draftKeyTerms}
271
+ isLoading={isLoading}
272
+ onQueryChange={setDraftQuery}
273
+ onKeyTermsChange={(id, values) => setDraftKeyTerms((current) => ({ ...current, [id]: values }))}
274
+ onSubmit={submitSearch}
275
+ />
276
+ )}
277
+ {navigation.length > 0 && definition.layout?.navigation_position === 'top' && (
278
+ <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">{navigationWidgets}</div>
279
+ )}
280
+ </FullHeightLayout.Fixed>
281
+ <FullHeightLayout.Body className="p-0">
282
+ <div
283
+ className={
284
+ hasSidebarNavigation
285
+ ? isWorklist
286
+ ? 'grid min-h-full lg:grid-cols-[minmax(0,1fr)_18rem]'
287
+ : 'grid min-h-full lg:grid-cols-[18rem_minmax(0,1fr)]'
288
+ : 'min-h-full'
289
+ }
290
+ >
291
+ {hasSidebarNavigation && (
292
+ <aside
293
+ className={
294
+ isWorklist
295
+ ? 'space-y-5 border-b p-4 lg:order-2 lg:border-s lg:border-b-0'
296
+ : 'space-y-5 border-b p-4 lg:border-e lg:border-b-0'
297
+ }
298
+ >
299
+ {navigationWidgets}
300
+ </aside>
301
+ )}
302
+ <main className={`min-w-0 space-y-4 p-4 ${isWorklist ? 'lg:order-1' : ''}`}>
303
+ {error && (
304
+ <ErrorBox
305
+ title={t('store.searchFailed')}
306
+ action={() => void runRequest(request, false)}
307
+ actionLabel={t('agent.retry')}
308
+ >
309
+ {t('store.searchFailed')}
310
+ </ErrorBox>
311
+ )}
312
+ {result.search.warnings.length > 0 && (
313
+ <MessageBox status="warning" title={t('view.warning')}>
314
+ <ul className="list-disc space-y-1 ps-4">
315
+ {result.search.warnings.map((warning) => (
316
+ <li key={`${warning.code}-${warning.path ?? ''}`}>{warning.message}</li>
317
+ ))}
318
+ </ul>
319
+ </MessageBox>
320
+ )}
321
+ <div className="flex flex-wrap items-center justify-between gap-3">
322
+ <div className="flex items-center gap-2 text-sm text-muted">
323
+ <span>{t('view.resultsCount', { count: result.total })}</span>
324
+ {isLoading && <Spinner size="sm" />}
325
+ </div>
326
+ <div className="flex flex-wrap items-center gap-3">
327
+ {resultsConfiguration?.allow_display_switch &&
328
+ resultsConfiguration.displays.length > 1 && (
329
+ <div className="flex items-center gap-2">
330
+ <span className="text-sm text-muted">{t('view.display')}</span>
331
+ <SelectBox
332
+ options={resultsConfiguration.displays}
333
+ value={display}
334
+ onChange={(option) =>
335
+ applyRequest({ ...request, display: option.id, offset: undefined })
336
+ }
337
+ optionLabel={(option) => option.label}
338
+ by="id"
339
+ disabled={isLoading}
340
+ aria-label={t('view.display')}
341
+ className="min-w-36"
342
+ />
343
+ </div>
344
+ )}
345
+ {resultsConfiguration?.sort_options && resultsConfiguration.sort_options.length > 0 && (
346
+ <div className="flex items-center gap-2">
347
+ <span className="text-sm text-muted">{t('view.sort')}</span>
348
+ <SelectBox
349
+ options={resultsConfiguration.sort_options}
350
+ value={resultsConfiguration.sort_options.find(
351
+ (option) => option.id === effectiveSortId,
352
+ )}
353
+ onChange={(option) =>
354
+ applyRequest({ ...request, sort: option.id, offset: undefined })
355
+ }
356
+ optionLabel={(option) => option.label}
357
+ by="id"
358
+ disabled={isLoading}
359
+ aria-label={t('view.sort')}
360
+ className="min-w-44"
361
+ />
362
+ </div>
363
+ )}
364
+ </div>
365
+ </div>
366
+ <ResultsRenderer
367
+ configuration={display}
368
+ definition={definition}
369
+ request={request}
370
+ result={result}
371
+ isLoading={isLoading}
372
+ onSortChange={(sort) => applyRequest({ ...request, sort, offset: undefined })}
373
+ onOpenHit={onOpenHit}
374
+ resolveMedia={resolveMedia}
375
+ />
376
+ {(hasPrevious || hasNext) && (
377
+ <nav className="flex items-center justify-center gap-2" aria-label={t('view.pagination')}>
378
+ <Button
379
+ type="button"
380
+ variant="outline"
381
+ disabled={!hasPrevious || isLoading}
382
+ onClick={() =>
383
+ applyRequest({
384
+ ...request,
385
+ offset: Math.max(0, offset - pageStep) || undefined,
386
+ })
387
+ }
388
+ >
389
+ <ChevronLeft className="size-4 cn-rtl-flip" />
390
+ {t('grounded.previousPage')}
391
+ </Button>
392
+ <Button
393
+ type="button"
394
+ variant="outline"
395
+ disabled={!hasNext || isLoading}
396
+ onClick={() => applyRequest({ ...request, offset: offset + pageStep })}
397
+ >
398
+ {t('grounded.nextPage')}
399
+ <ChevronRight className="size-4 cn-rtl-flip" />
400
+ </Button>
401
+ </nav>
402
+ )}
403
+ </main>
404
+ </div>
405
+ </FullHeightLayout.Body>
406
+ </FullHeightLayout>
407
+ );
408
+ }
@@ -0,0 +1,86 @@
1
+ import { cleanup, fireEvent, screen } from '@testing-library/react';
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
3
+ import { renderWithProviders } from '../../__tests__/test-utils.js';
4
+ import { DefaultViewNavigation } from './ViewNavigation.js';
5
+
6
+ describe('DefaultViewNavigation', () => {
7
+ afterEach(cleanup);
8
+
9
+ it('keeps selected collection labels visible above the available nodes', () => {
10
+ const onChange = vi.fn();
11
+ renderWithProviders(
12
+ <DefaultViewNavigation
13
+ configuration={{ id: 'collections', label: 'Collections', source: 'collection' }}
14
+ result={{
15
+ id: 'collections',
16
+ selected: ['selected-id'],
17
+ nodes: [
18
+ { id: 'selected-id', label: 'Priority orders', count: 12, selected: true },
19
+ { id: 'child-id', label: 'Escalated', count: 3 },
20
+ ],
21
+ }}
22
+ isLoading={false}
23
+ onChange={onChange}
24
+ />,
25
+ );
26
+
27
+ expect(screen.getAllByText('Priority orders')).toHaveLength(2);
28
+ expect(screen.queryByText('selected-id')).toBeNull();
29
+ fireEvent.click(screen.getByRole('checkbox', { name: /Priority orders/ }));
30
+ expect(onChange).toHaveBeenCalledWith([]);
31
+ });
32
+
33
+ it('lets users remove a selected location after drill-down hides the parent node', () => {
34
+ const onChange = vi.fn();
35
+ renderWithProviders(
36
+ <DefaultViewNavigation
37
+ configuration={{ id: 'location', label: 'Location', source: 'location', multi_select: true }}
38
+ result={{
39
+ id: 'location',
40
+ selected: ['/Customers/Acme'],
41
+ nodes: [{ id: '/Customers/Acme/Orders', label: 'Orders', count: 8 }],
42
+ }}
43
+ isLoading={false}
44
+ onChange={onChange}
45
+ />,
46
+ );
47
+
48
+ fireEvent.click(screen.getByRole('button', { name: 'Remove /Customers/Acme' }));
49
+ expect(onChange).toHaveBeenCalledWith([]);
50
+ });
51
+
52
+ it('renders property hierarchy buckets as drill-down choices with clickable breadcrumbs', () => {
53
+ const onChange = vi.fn();
54
+ renderWithProviders(
55
+ <DefaultViewNavigation
56
+ configuration={{
57
+ id: 'geography',
58
+ label: 'Geography',
59
+ source: 'hierarchy',
60
+ levels: [
61
+ { id: 'state', label: 'State', field: 'properties.state' },
62
+ { id: 'city', label: 'City', field: 'properties.city' },
63
+ ],
64
+ }}
65
+ result={{
66
+ id: 'geography',
67
+ selected: ['h1:florida'],
68
+ breadcrumbs: [{ id: 'h1:florida', label: 'FL', count: 0, selected: true }],
69
+ nodes: [
70
+ { id: 'h1:miami', label: 'Miami', count: 8 },
71
+ { id: 'h1:orlando', label: 'Orlando', count: 4 },
72
+ ],
73
+ }}
74
+ isLoading={false}
75
+ onChange={onChange}
76
+ />,
77
+ );
78
+
79
+ expect(screen.queryByText('h1:florida')).toBeNull();
80
+ expect(screen.getByRole('navigation', { name: 'Geography path' })).not.toBeNull();
81
+ fireEvent.click(screen.getByRole('button', { name: /Miami/ }));
82
+ expect(onChange).toHaveBeenLastCalledWith(['h1:miami']);
83
+ fireEvent.click(screen.getByRole('button', { name: 'FL' }));
84
+ expect(onChange).toHaveBeenLastCalledWith(['h1:florida']);
85
+ });
86
+ });
@@ -0,0 +1,187 @@
1
+ import type { ViewNavigationNode } from '@vertesia/common';
2
+ import { Button, Checkbox, SelectBox } from '@vertesia/ui/core';
3
+ import { useUITranslation } from '@vertesia/ui/i18n';
4
+ import { ChevronRight, X } from 'lucide-react';
5
+ import { useId } from 'react';
6
+ import type { ViewNavigationRendererProps } from './types.js';
7
+
8
+ function nextSelection(current: string[], id: string, selected: boolean, multiSelect: boolean | undefined): string[] {
9
+ if (!selected) return current.filter((value) => value !== id);
10
+ if (multiSelect === false) return [id];
11
+ return current.includes(id) ? current : [...current, id];
12
+ }
13
+
14
+ function NodeLabel({ node }: { node: ViewNavigationNode }) {
15
+ return (
16
+ <span className="flex min-w-0 flex-1 items-center justify-between gap-2">
17
+ <span className="truncate">{node.label}</span>
18
+ <span className="text-xs tabular-nums text-muted">{node.count}</span>
19
+ </span>
20
+ );
21
+ }
22
+
23
+ export function DefaultViewNavigation({ configuration, result, isLoading, onChange }: ViewNavigationRendererProps) {
24
+ const { t } = useUITranslation();
25
+ const idPrefix = useId();
26
+ const presentation =
27
+ configuration.presentation ??
28
+ (configuration.source === 'location' || configuration.source === 'hierarchy' ? 'tree' : 'list');
29
+ const multiSelect = configuration.source === 'hierarchy' ? false : configuration.multi_select;
30
+ const breadcrumbs = result.breadcrumbs ?? [];
31
+
32
+ const toggle = (id: string, selected: boolean) => {
33
+ onChange(nextSelection(result.selected, id, selected, multiSelect));
34
+ };
35
+
36
+ return (
37
+ <section className="space-y-2" aria-labelledby={`${idPrefix}-label`}>
38
+ <div className="flex items-center justify-between gap-2">
39
+ <h2 id={`${idPrefix}-label`} className="text-sm font-semibold">
40
+ {configuration.label}
41
+ </h2>
42
+ {result.selected.length > 0 && (
43
+ <Button
44
+ type="button"
45
+ variant="ghost"
46
+ size="sm"
47
+ disabled={isLoading}
48
+ onClick={() => onChange([])}
49
+ aria-label={`${t('filter.clearAll')}: ${configuration.label}`}
50
+ >
51
+ <X className="size-3.5" />
52
+ {t('filter.clearAll')}
53
+ </Button>
54
+ )}
55
+ </div>
56
+
57
+ {configuration.source === 'hierarchy' && breadcrumbs.length > 0 && (
58
+ <nav aria-label={`${configuration.label} path`}>
59
+ <ol className="flex flex-wrap items-center gap-1 text-sm">
60
+ {breadcrumbs.map((node, index) => (
61
+ <li key={node.id} className="flex items-center gap-1">
62
+ {index > 0 && <ChevronRight aria-hidden="true" className="size-3.5 text-muted" />}
63
+ <Button
64
+ type="button"
65
+ variant="ghost"
66
+ size="sm"
67
+ disabled={isLoading}
68
+ onClick={() => onChange([node.id])}
69
+ aria-current={index === breadcrumbs.length - 1 ? 'page' : undefined}
70
+ >
71
+ {node.label}
72
+ </Button>
73
+ </li>
74
+ ))}
75
+ </ol>
76
+ </nav>
77
+ )}
78
+
79
+ {result.selected.length > 0 &&
80
+ (configuration.source === 'location' || configuration.source === 'collection') && (
81
+ <div className="flex flex-wrap gap-1">
82
+ {result.selected.map((value) => {
83
+ const node = result.nodes.find((candidate) => candidate.id === value);
84
+ const label = node?.label ?? value;
85
+ return (
86
+ <Button
87
+ key={value}
88
+ type="button"
89
+ variant="secondary"
90
+ size="sm"
91
+ disabled={isLoading}
92
+ onClick={() => toggle(value, false)}
93
+ aria-label={t('view.removeSelection', { value: label })}
94
+ >
95
+ {label}
96
+ <X aria-hidden="true" className="size-3.5" />
97
+ </Button>
98
+ );
99
+ })}
100
+ </div>
101
+ )}
102
+
103
+ {presentation === 'select' && multiSelect === false ? (
104
+ <SelectBox<ViewNavigationNode>
105
+ options={result.nodes}
106
+ value={result.nodes.find((node) => result.selected.includes(node.id))}
107
+ onChange={(node) => onChange([node.id])}
108
+ optionLabel={(node) => `${node.label} (${node.count})`}
109
+ by="id"
110
+ disabled={isLoading}
111
+ placeholder={configuration.label}
112
+ aria-label={configuration.label}
113
+ />
114
+ ) : presentation === 'select' ? (
115
+ <SelectBox<ViewNavigationNode>
116
+ multiple
117
+ options={result.nodes}
118
+ value={result.nodes.filter((node) => result.selected.includes(node.id))}
119
+ onChange={(nodes) => onChange(nodes.map((node) => node.id))}
120
+ optionLabel={(node) => `${node.label} (${node.count})`}
121
+ by="id"
122
+ disabled={isLoading}
123
+ placeholder={configuration.label}
124
+ aria-label={configuration.label}
125
+ />
126
+ ) : presentation === 'chips' ? (
127
+ <div className="flex flex-wrap gap-2">
128
+ {result.nodes.map((node) => (
129
+ <Button
130
+ type="button"
131
+ variant={result.selected.includes(node.id) ? 'secondary' : 'outline'}
132
+ size="sm"
133
+ key={node.id}
134
+ disabled={isLoading}
135
+ onClick={() => toggle(node.id, !result.selected.includes(node.id))}
136
+ >
137
+ {node.label}
138
+ <span className="text-xs tabular-nums text-muted">{node.count}</span>
139
+ </Button>
140
+ ))}
141
+ </div>
142
+ ) : configuration.source === 'hierarchy' ? (
143
+ <div className="space-y-1">
144
+ {result.nodes.map((node) => (
145
+ <Button
146
+ type="button"
147
+ variant={result.selected.includes(node.id) ? 'secondary' : 'ghost'}
148
+ className="w-full justify-start"
149
+ key={node.id}
150
+ disabled={isLoading}
151
+ onClick={() => onChange([node.id])}
152
+ >
153
+ <NodeLabel node={node} />
154
+ {node.expandable && (
155
+ <ChevronRight aria-hidden="true" className="size-4 shrink-0 text-muted" />
156
+ )}
157
+ </Button>
158
+ ))}
159
+ </div>
160
+ ) : (
161
+ <div className="space-y-1">
162
+ {result.nodes.map((node, index) => {
163
+ const nodeId = `${idPrefix}-${index}`;
164
+ return (
165
+ <div
166
+ key={node.id}
167
+ className="flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-muted"
168
+ >
169
+ <Checkbox
170
+ id={nodeId}
171
+ checked={result.selected.includes(node.id)}
172
+ disabled={isLoading}
173
+ onCheckedChange={(checked) => toggle(node.id, checked === true)}
174
+ />
175
+ <label htmlFor={nodeId} className="flex min-w-0 flex-1 cursor-pointer text-sm">
176
+ <NodeLabel node={node} />
177
+ </label>
178
+ </div>
179
+ );
180
+ })}
181
+ </div>
182
+ )}
183
+
184
+ {result.nodes.length === 0 && <p className="text-sm text-muted">{t('filter.noAvailableFilters')}</p>}
185
+ </section>
186
+ );
187
+ }