@vertesia/ui 1.5.0-dev.20260807.073259Z → 1.5.0-dev.20260826.064249Z

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 (432) hide show
  1. package/README.md +1 -7
  2. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js +1 -1
  3. package/lib/core/components/shadcn/filters/comboBox/DateCombobox.js.map +1 -1
  4. package/lib/core/components/shadcn/filters/filter/dateFilter.d.ts.map +1 -1
  5. package/lib/core/components/shadcn/filters/filter/dateFilter.js +1 -1
  6. package/lib/core/components/shadcn/filters/filter/dateFilter.js.map +1 -1
  7. package/lib/core/components/shadcn/filters/filters.d.ts.map +1 -1
  8. package/lib/core/components/shadcn/filters/filters.js +1 -1
  9. package/lib/core/components/shadcn/filters/filters.js.map +1 -1
  10. package/lib/core/components/shadcn/index.d.ts +1 -0
  11. package/lib/core/components/shadcn/index.d.ts.map +1 -1
  12. package/lib/core/components/shadcn/index.js +1 -0
  13. package/lib/core/components/shadcn/index.js.map +1 -1
  14. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  15. package/lib/core/components/shadcn/modal/dialog.js +1 -3
  16. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  17. package/lib/core/components/shadcn/overflowTabs.d.ts +59 -0
  18. package/lib/core/components/shadcn/overflowTabs.d.ts.map +1 -0
  19. package/lib/core/components/shadcn/overflowTabs.js +173 -0
  20. package/lib/core/components/shadcn/overflowTabs.js.map +1 -0
  21. package/lib/core/components/shadcn/selectBox.js +2 -2
  22. package/lib/core/components/shadcn/selectBox.js.map +1 -1
  23. package/lib/core/components/shadcn/theme/ThemeProvider.d.ts +3 -1
  24. package/lib/core/components/shadcn/theme/ThemeProvider.d.ts.map +1 -1
  25. package/lib/core/components/shadcn/theme/ThemeProvider.js +8 -9
  26. package/lib/core/components/shadcn/theme/ThemeProvider.js.map +1 -1
  27. package/lib/core/utils/dayjs.d.ts +12 -0
  28. package/lib/core/utils/dayjs.d.ts.map +1 -0
  29. package/lib/core/utils/dayjs.js +16 -0
  30. package/lib/core/utils/dayjs.js.map +1 -0
  31. package/lib/env/index.d.ts +17 -0
  32. package/lib/env/index.d.ts.map +1 -1
  33. package/lib/env/index.js +18 -1
  34. package/lib/env/index.js.map +1 -1
  35. package/lib/features/agent/PayloadBuilder.d.ts +1 -0
  36. package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
  37. package/lib/features/agent/PayloadBuilder.js +22 -5
  38. package/lib/features/agent/PayloadBuilder.js.map +1 -1
  39. package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
  40. package/lib/features/agent/chat/AgentRightPanel.js +3 -135
  41. package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
  42. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  43. package/lib/features/agent/chat/ArtifactsTab.js +1 -1
  44. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  45. package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
  46. package/lib/features/agent/chat/AskUserWidget.js +19 -4
  47. package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
  48. package/lib/features/agent/chat/ModernAgentConversation.d.ts +6 -0
  49. package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  50. package/lib/features/agent/chat/ModernAgentConversation.js +99 -29
  51. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  52. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
  53. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +10 -9
  54. package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
  55. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  56. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +5 -8
  57. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  58. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
  59. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +45 -4
  60. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
  61. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +1 -1
  62. package/lib/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
  63. package/lib/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  64. package/lib/features/agent/chat/ModernAgentOutput/Header.js +3 -3
  65. package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  66. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  67. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +1 -1
  68. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  69. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
  70. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js +1 -1
  71. package/lib/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
  72. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +1 -1
  73. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  74. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.d.ts.map +1 -1
  75. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +9 -121
  76. package/lib/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  77. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +6 -0
  78. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  79. package/lib/features/agent/chat/ModernAgentOutput/utils.js +19 -11
  80. package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  81. package/lib/features/agent/chat/VegaLiteChart.d.ts.map +1 -1
  82. package/lib/features/agent/chat/VegaLiteChart.js +11 -3
  83. package/lib/features/agent/chat/VegaLiteChart.js.map +1 -1
  84. package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
  85. package/lib/features/agent/chat/hooks/useAgentStream.js +3 -0
  86. package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
  87. package/lib/features/document-viewer/UniversalDocumentViewer.d.ts.map +1 -1
  88. package/lib/features/document-viewer/UniversalDocumentViewer.js +1 -1
  89. package/lib/features/document-viewer/UniversalDocumentViewer.js.map +1 -1
  90. package/lib/features/facets/AgentRunnerFacetsNav.d.ts +14 -2
  91. package/lib/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
  92. package/lib/features/facets/AgentRunnerFacetsNav.js +20 -2
  93. package/lib/features/facets/AgentRunnerFacetsNav.js.map +1 -1
  94. package/lib/features/facets/CollectionsFacetsNav.d.ts +3 -3
  95. package/lib/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
  96. package/lib/features/facets/CollectionsFacetsNav.js +6 -1
  97. package/lib/features/facets/CollectionsFacetsNav.js.map +1 -1
  98. package/lib/features/facets/DocumentsFacetsNav.d.ts +3 -3
  99. package/lib/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
  100. package/lib/features/facets/DocumentsFacetsNav.js +20 -8
  101. package/lib/features/facets/DocumentsFacetsNav.js.map +1 -1
  102. package/lib/features/facets/InteractionsFacetsNav.d.ts +3 -3
  103. package/lib/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  104. package/lib/features/facets/InteractionsFacetsNav.js +11 -1
  105. package/lib/features/facets/InteractionsFacetsNav.js.map +1 -1
  106. package/lib/features/facets/PromptsFacetsNav.d.ts +3 -3
  107. package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
  108. package/lib/features/facets/PromptsFacetsNav.js +6 -1
  109. package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
  110. package/lib/features/facets/RunsFacetsNav.d.ts +4 -14
  111. package/lib/features/facets/RunsFacetsNav.d.ts.map +1 -1
  112. package/lib/features/facets/RunsFacetsNav.js +26 -15
  113. package/lib/features/facets/RunsFacetsNav.js.map +1 -1
  114. package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts +4 -3
  115. package/lib/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
  116. package/lib/features/facets/WorkflowExecutionsFacetsNav.js +18 -10
  117. package/lib/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -1
  118. package/lib/features/facets/index.d.ts +1 -1
  119. package/lib/features/facets/index.d.ts.map +1 -1
  120. package/lib/features/facets/index.js.map +1 -1
  121. package/lib/features/facets/utils/SearchInterface.d.ts +4 -3
  122. package/lib/features/facets/utils/SearchInterface.d.ts.map +1 -1
  123. package/lib/features/facets/utils/SearchInterface.js +4 -0
  124. package/lib/features/facets/utils/SearchInterface.js.map +1 -1
  125. package/lib/features/layout/GenericPageNavHeader.d.ts +8 -1
  126. package/lib/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  127. package/lib/features/layout/GenericPageNavHeader.js +9 -1
  128. package/lib/features/layout/GenericPageNavHeader.js.map +1 -1
  129. package/lib/features/magic-pdf/DownloadPopover.d.ts +3 -2
  130. package/lib/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
  131. package/lib/features/magic-pdf/DownloadPopover.js.map +1 -1
  132. package/lib/features/magic-pdf/GroundedExtractionView.d.ts.map +1 -1
  133. package/lib/features/magic-pdf/GroundedExtractionView.js +51 -64
  134. package/lib/features/magic-pdf/GroundedExtractionView.js.map +1 -1
  135. package/lib/features/oauth/McpConnectionsButton.d.ts +1 -1
  136. package/lib/features/oauth/McpConnectionsButton.d.ts.map +1 -1
  137. package/lib/features/oauth/McpConnectionsButton.js +2 -2
  138. package/lib/features/oauth/McpConnectionsButton.js.map +1 -1
  139. package/lib/features/oauth/McpConnectionsDialog.d.ts +1 -1
  140. package/lib/features/oauth/McpConnectionsDialog.js +2 -2
  141. package/lib/features/oauth/McpConnectionsDialog.js.map +1 -1
  142. package/lib/features/oauth/useMcpConnections.d.ts +4 -5
  143. package/lib/features/oauth/useMcpConnections.d.ts.map +1 -1
  144. package/lib/features/oauth/useMcpConnections.js +20 -4
  145. package/lib/features/oauth/useMcpConnections.js.map +1 -1
  146. package/lib/features/pdf-viewer/PdfPageRenderer.d.ts.map +1 -1
  147. package/lib/features/pdf-viewer/PdfPageRenderer.js +9 -11
  148. package/lib/features/pdf-viewer/PdfPageRenderer.js.map +1 -1
  149. package/lib/features/pdf-viewer/lazyReactPdf.d.ts +10 -0
  150. package/lib/features/pdf-viewer/lazyReactPdf.d.ts.map +1 -0
  151. package/lib/features/pdf-viewer/lazyReactPdf.js +25 -0
  152. package/lib/features/pdf-viewer/lazyReactPdf.js.map +1 -0
  153. package/lib/features/store/collections/CollectionsTable.d.ts.map +1 -1
  154. package/lib/features/store/collections/CollectionsTable.js +1 -3
  155. package/lib/features/store/collections/CollectionsTable.js.map +1 -1
  156. package/lib/features/store/collections/EditCollectionView.js +1 -1
  157. package/lib/features/store/collections/EditCollectionView.js.map +1 -1
  158. package/lib/features/store/objects/ExportPropertiesModal.d.ts +3 -1
  159. package/lib/features/store/objects/ExportPropertiesModal.d.ts.map +1 -1
  160. package/lib/features/store/objects/ExportPropertiesModal.js +5 -5
  161. package/lib/features/store/objects/ExportPropertiesModal.js.map +1 -1
  162. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  163. package/lib/features/store/objects/components/ContentOverview.js +4 -10
  164. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  165. package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
  166. package/lib/features/store/objects/components/TextEditorPanel.js +8 -3
  167. package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
  168. package/lib/features/store/objects/layout/renderers.d.ts.map +1 -1
  169. package/lib/features/store/objects/layout/renderers.js +1 -5
  170. package/lib/features/store/objects/layout/renderers.js.map +1 -1
  171. package/lib/features/store/objects/search/DocumentSearchContext.d.ts +29 -62
  172. package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  173. package/lib/features/store/objects/search/DocumentSearchContext.js +2 -0
  174. package/lib/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  175. package/lib/features/store/objects/upload/DocumentUploadModal.d.ts +6 -1
  176. package/lib/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  177. package/lib/features/store/objects/upload/DocumentUploadModal.js +4 -3
  178. package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  179. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
  180. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js +2 -2
  181. package/lib/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
  182. package/lib/features/store/types/ContentObjectTypesTable.d.ts.map +1 -1
  183. package/lib/features/store/types/ContentObjectTypesTable.js +1 -3
  184. package/lib/features/store/types/ContentObjectTypesTable.js.map +1 -1
  185. package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
  186. package/lib/features/store/types/IntakePolicyEditor.js +11 -1
  187. package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
  188. package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
  189. package/lib/features/store/types/ObjectSchemaEditor.js +6 -2
  190. package/lib/features/store/types/ObjectSchemaEditor.js.map +1 -1
  191. package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
  192. package/lib/features/store/types/TableLayoutEditor.js +2 -0
  193. package/lib/features/store/types/TableLayoutEditor.js.map +1 -1
  194. package/lib/features/store/types/TypeRegistry.d.ts +272 -0
  195. package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
  196. package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +271 -0
  197. package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
  198. package/lib/features/user/UserInfo.d.ts.map +1 -1
  199. package/lib/features/user/UserInfo.js +2 -4
  200. package/lib/features/user/UserInfo.js.map +1 -1
  201. package/lib/features/views/ViewActions.d.ts +32 -0
  202. package/lib/features/views/ViewActions.d.ts.map +1 -0
  203. package/lib/features/views/ViewActions.js +186 -0
  204. package/lib/features/views/ViewActions.js.map +1 -0
  205. package/lib/features/views/ViewDropTarget.d.ts +15 -0
  206. package/lib/features/views/ViewDropTarget.d.ts.map +1 -0
  207. package/lib/features/views/ViewDropTarget.js +79 -0
  208. package/lib/features/views/ViewDropTarget.js.map +1 -0
  209. package/lib/features/views/ViewExperience.d.ts +3 -2
  210. package/lib/features/views/ViewExperience.d.ts.map +1 -1
  211. package/lib/features/views/ViewExperience.js +103 -12
  212. package/lib/features/views/ViewExperience.js.map +1 -1
  213. package/lib/features/views/ViewNavigation.d.ts +1 -1
  214. package/lib/features/views/ViewNavigation.d.ts.map +1 -1
  215. package/lib/features/views/ViewNavigation.js +14 -5
  216. package/lib/features/views/ViewNavigation.js.map +1 -1
  217. package/lib/features/views/ViewResults.d.ts +1 -1
  218. package/lib/features/views/ViewResults.d.ts.map +1 -1
  219. package/lib/features/views/ViewResults.js +124 -34
  220. package/lib/features/views/ViewResults.js.map +1 -1
  221. package/lib/features/views/index.d.ts +1 -0
  222. package/lib/features/views/index.d.ts.map +1 -1
  223. package/lib/features/views/index.js +1 -0
  224. package/lib/features/views/index.js.map +1 -1
  225. package/lib/features/views/types.d.ts +46 -1
  226. package/lib/features/views/types.d.ts.map +1 -1
  227. package/lib/features/views/viewState.d.ts.map +1 -1
  228. package/lib/features/views/viewState.js +34 -0
  229. package/lib/features/views/viewState.js.map +1 -1
  230. package/lib/i18n/LanguageProvider.d.ts +3 -1
  231. package/lib/i18n/LanguageProvider.d.ts.map +1 -1
  232. package/lib/i18n/LanguageProvider.js +9 -7
  233. package/lib/i18n/LanguageProvider.js.map +1 -1
  234. package/lib/i18n/instance.d.ts +2 -0
  235. package/lib/i18n/instance.d.ts.map +1 -1
  236. package/lib/i18n/instance.js +45 -26
  237. package/lib/i18n/instance.js.map +1 -1
  238. package/lib/i18n/locales/ar.json +261 -15
  239. package/lib/i18n/locales/de.json +259 -13
  240. package/lib/i18n/locales/en.json +30 -4
  241. package/lib/i18n/locales/es.json +260 -14
  242. package/lib/i18n/locales/fr.json +259 -13
  243. package/lib/i18n/locales/it.json +259 -13
  244. package/lib/i18n/locales/ja.json +257 -10
  245. package/lib/i18n/locales/ko.json +257 -10
  246. package/lib/i18n/locales/pt.json +259 -13
  247. package/lib/i18n/locales/ru.json +256 -10
  248. package/lib/i18n/locales/tr.json +256 -10
  249. package/lib/i18n/locales/zh-TW.json +257 -10
  250. package/lib/i18n/locales/zh.json +257 -10
  251. package/lib/session/UserSessionProvider.d.ts.map +1 -1
  252. package/lib/session/UserSessionProvider.js +8 -16
  253. package/lib/session/UserSessionProvider.js.map +1 -1
  254. package/lib/session/auth/composable.d.ts.map +1 -1
  255. package/lib/session/auth/composable.js +25 -19
  256. package/lib/session/auth/composable.js.map +1 -1
  257. package/lib/session/auth/firebase.js +1 -1
  258. package/lib/session/auth/firebase.js.map +1 -1
  259. package/lib/shell/VertesiaShell.d.ts.map +1 -1
  260. package/lib/shell/VertesiaShell.js +2 -1
  261. package/lib/shell/VertesiaShell.js.map +1 -1
  262. package/lib/shell/apps/AppInstallationProvider.d.ts +4 -2
  263. package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
  264. package/lib/shell/apps/IframeAppContextSync.d.ts +3 -0
  265. package/lib/shell/apps/IframeAppContextSync.d.ts.map +1 -0
  266. package/lib/shell/apps/IframeAppContextSync.js +95 -0
  267. package/lib/shell/apps/IframeAppContextSync.js.map +1 -0
  268. package/lib/shell/apps/iframe-auth.d.ts +55 -0
  269. package/lib/shell/apps/iframe-auth.d.ts.map +1 -0
  270. package/lib/shell/apps/iframe-auth.js +154 -0
  271. package/lib/shell/apps/iframe-auth.js.map +1 -0
  272. package/lib/shell/apps/index.d.ts +2 -0
  273. package/lib/shell/apps/index.d.ts.map +1 -1
  274. package/lib/shell/apps/index.js +2 -0
  275. package/lib/shell/apps/index.js.map +1 -1
  276. package/lib/vertesia-ui-core.js +4 -4
  277. package/lib/vertesia-ui-core.js.map +1 -1
  278. package/lib/vertesia-ui-env.js +1 -1
  279. package/lib/vertesia-ui-env.js.map +1 -1
  280. package/lib/vertesia-ui-features.js +32 -34
  281. package/lib/vertesia-ui-features.js.map +1 -1
  282. package/lib/vertesia-ui-i18n.js +16 -16
  283. package/lib/vertesia-ui-i18n.js.map +1 -1
  284. package/lib/vertesia-ui-rich-text.js +4 -4
  285. package/lib/vertesia-ui-rich-text.js.map +1 -1
  286. package/lib/vertesia-ui-router.js +1 -1
  287. package/lib/vertesia-ui-router.js.map +1 -1
  288. package/lib/vertesia-ui-session.js +1 -1
  289. package/lib/vertesia-ui-session.js.map +1 -1
  290. package/lib/vertesia-ui-shell.js +1 -1
  291. package/lib/vertesia-ui-shell.js.map +1 -1
  292. package/lib/vertesia-ui-widgets.js +20 -20
  293. package/lib/vertesia-ui-widgets.js.map +1 -1
  294. package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  295. package/lib/widgets/markdown/MarkdownRenderer.js +43 -2
  296. package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
  297. package/lib/widgets/markdown/MermaidDiagram.d.ts.map +1 -1
  298. package/lib/widgets/markdown/MermaidDiagram.js +35 -22
  299. package/lib/widgets/markdown/MermaidDiagram.js.map +1 -1
  300. package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  301. package/lib/widgets/monacoEditor/MonacoEditor.js +14 -10
  302. package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  303. package/lib/widgets/xml-viewer/hooks/useCollapsible.d.ts +1 -1
  304. package/package.json +24 -29
  305. package/src/core/components/shadcn/filters/comboBox/DateCombobox.tsx +1 -1
  306. package/src/core/components/shadcn/filters/filter/dateFilter.tsx +1 -1
  307. package/src/core/components/shadcn/filters/filters.tsx +1 -1
  308. package/src/core/components/shadcn/index.ts +1 -0
  309. package/src/core/components/shadcn/modal/dialog.test.tsx +35 -0
  310. package/src/core/components/shadcn/modal/dialog.tsx +0 -4
  311. package/src/core/components/shadcn/overflowTabs.tsx +320 -0
  312. package/src/core/components/shadcn/selectBox.tsx +2 -2
  313. package/src/core/components/shadcn/theme/ThemeProvider.tsx +10 -9
  314. package/src/core/utils/dayjs.ts +17 -0
  315. package/src/css/base.css +78 -0
  316. package/src/env/index.test.ts +94 -0
  317. package/src/env/index.ts +36 -1
  318. package/src/features/agent/PayloadBuilder.test.ts +68 -0
  319. package/src/features/agent/PayloadBuilder.tsx +28 -4
  320. package/src/features/agent/chat/AgentRightPanel.tsx +2 -252
  321. package/src/features/agent/chat/ArtifactsTab.tsx +1 -0
  322. package/src/features/agent/chat/AskUserWidget.test.tsx +20 -1
  323. package/src/features/agent/chat/AskUserWidget.tsx +22 -6
  324. package/src/features/agent/chat/ModernAgentConversation.test.tsx +160 -0
  325. package/src/features/agent/chat/ModernAgentConversation.tsx +111 -31
  326. package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +86 -67
  327. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +90 -7
  328. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +4 -6
  329. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.test.ts +103 -1
  330. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +50 -4
  331. package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +1 -1
  332. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +18 -1
  333. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +1 -1
  334. package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +1 -1
  335. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +1 -1
  336. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +37 -167
  337. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +94 -0
  338. package/src/features/agent/chat/ModernAgentOutput/utils.ts +19 -10
  339. package/src/features/agent/chat/VegaLiteChart.tsx +32 -14
  340. package/src/features/agent/chat/hooks/useAgentStream.test.tsx +18 -0
  341. package/src/features/agent/chat/hooks/useAgentStream.ts +3 -0
  342. package/src/features/document-viewer/UniversalDocumentViewer.tsx +1 -1
  343. package/src/features/facets/AgentRunnerFacetsNav.tsx +44 -4
  344. package/src/features/facets/CollectionsFacetsNav.tsx +15 -4
  345. package/src/features/facets/DocumentsFacetsNav.tsx +25 -8
  346. package/src/features/facets/FacetQueryHandlers.test.ts +84 -0
  347. package/src/features/facets/InteractionsFacetsNav.tsx +20 -4
  348. package/src/features/facets/PromptsFacetsNav.tsx +15 -4
  349. package/src/features/facets/RunsFacetsNav.test.ts +59 -0
  350. package/src/features/facets/RunsFacetsNav.tsx +40 -30
  351. package/src/features/facets/WorkflowExecutionsFacetsNav.test.ts +57 -0
  352. package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +36 -16
  353. package/src/features/facets/index.ts +1 -0
  354. package/src/features/facets/utils/SearchInterface.tsx +12 -3
  355. package/src/features/layout/GenericPageNavHeader.tsx +16 -0
  356. package/src/features/magic-pdf/DownloadPopover.tsx +1 -2
  357. package/src/features/magic-pdf/GroundedExtractionView.test.tsx +7 -1
  358. package/src/features/magic-pdf/GroundedExtractionView.tsx +162 -242
  359. package/src/features/oauth/McpConnectionsButton.test.tsx +18 -1
  360. package/src/features/oauth/McpConnectionsButton.tsx +6 -2
  361. package/src/features/oauth/McpConnectionsDialog.tsx +3 -3
  362. package/src/features/oauth/useMcpConnections.test.ts +1 -0
  363. package/src/features/oauth/useMcpConnections.ts +24 -7
  364. package/src/features/pdf-viewer/PdfPageRenderer.tsx +76 -71
  365. package/src/features/pdf-viewer/lazyReactPdf.ts +33 -0
  366. package/src/features/store/collections/CollectionsTable.tsx +1 -4
  367. package/src/features/store/collections/EditCollectionView.tsx +1 -1
  368. package/src/features/store/objects/ExportPropertiesModal.tsx +25 -16
  369. package/src/features/store/objects/components/ContentOverview.tsx +2 -28
  370. package/src/features/store/objects/components/TextEditorPanel.tsx +13 -3
  371. package/src/features/store/objects/layout/renderers.tsx +1 -6
  372. package/src/features/store/objects/search/DocumentSearchContext.ts +4 -2
  373. package/src/features/store/objects/upload/DocumentUploadModal.tsx +10 -3
  374. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +15 -6
  375. package/src/features/store/types/ContentObjectTypesTable.tsx +1 -4
  376. package/src/features/store/types/IntakePolicyEditor.tsx +11 -1
  377. package/src/features/store/types/ObjectSchemaEditor.tsx +6 -2
  378. package/src/features/store/types/TableLayoutEditor.tsx +2 -0
  379. package/src/features/user/UserInfo.test.tsx +10 -0
  380. package/src/features/user/UserInfo.tsx +2 -7
  381. package/src/features/views/ViewActions.test.tsx +80 -0
  382. package/src/features/views/ViewActions.tsx +352 -0
  383. package/src/features/views/ViewDropTarget.test.tsx +150 -0
  384. package/src/features/views/ViewDropTarget.tsx +140 -0
  385. package/src/features/views/ViewExperience.test.tsx +72 -0
  386. package/src/features/views/ViewExperience.tsx +189 -22
  387. package/src/features/views/ViewMedia.test.tsx +180 -0
  388. package/src/features/views/ViewNavigation.test.tsx +42 -0
  389. package/src/features/views/ViewNavigation.tsx +43 -5
  390. package/src/features/views/ViewResults.tsx +243 -26
  391. package/src/features/views/index.ts +1 -0
  392. package/src/features/views/types.ts +50 -0
  393. package/src/features/views/viewState.test.ts +7 -1
  394. package/src/features/views/viewState.ts +32 -0
  395. package/src/i18n/LanguageProvider.tsx +15 -8
  396. package/src/i18n/instance.test.ts +30 -0
  397. package/src/i18n/instance.ts +67 -40
  398. package/src/i18n/locales/ar.json +1157 -911
  399. package/src/i18n/locales/de.json +1113 -867
  400. package/src/i18n/locales/en.json +30 -4
  401. package/src/i18n/locales/es.json +1124 -878
  402. package/src/i18n/locales/fr.json +1124 -878
  403. package/src/i18n/locales/it.json +1124 -878
  404. package/src/i18n/locales/ja.json +1113 -866
  405. package/src/i18n/locales/ko.json +1113 -866
  406. package/src/i18n/locales/pt.json +1124 -878
  407. package/src/i18n/locales/ru.json +1135 -889
  408. package/src/i18n/locales/tr.json +1113 -867
  409. package/src/i18n/locales/zh-TW.json +1113 -866
  410. package/src/i18n/locales/zh.json +1113 -866
  411. package/src/i18n/rtl.test.ts +16 -7
  412. package/src/rich-text/VertesiaRichTextEditor.test.tsx +33 -1
  413. package/src/session/UserSessionProvider.tsx +8 -20
  414. package/src/session/auth/composable.scope.test.ts +1 -1
  415. package/src/session/auth/composable.test.ts +61 -1
  416. package/src/session/auth/composable.ts +29 -23
  417. package/src/session/auth/firebase.ts +1 -1
  418. package/src/shell/VertesiaShell.tsx +2 -0
  419. package/src/shell/apps/IframeAppContextSync.test.tsx +196 -0
  420. package/src/shell/apps/IframeAppContextSync.tsx +101 -0
  421. package/src/shell/apps/iframe-auth.test.ts +118 -0
  422. package/src/shell/apps/iframe-auth.ts +193 -0
  423. package/src/shell/apps/index.ts +2 -0
  424. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +12 -3
  425. package/src/widgets/markdown/MarkdownRenderer.tsx +50 -2
  426. package/src/widgets/markdown/MermaidDiagram.tsx +38 -22
  427. package/src/widgets/monacoEditor/MonacoEditor.tsx +27 -20
  428. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts +0 -25
  429. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.d.ts.map +0 -1
  430. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js +0 -42
  431. package/lib/features/magic-pdf/GroundedExtractionAssistantPanel.js.map +0 -1
  432. package/src/features/magic-pdf/GroundedExtractionAssistantPanel.tsx +0 -86
@@ -1,4 +1,4 @@
1
- import type { Collection, ContentObjectTypeCatalogEntry, DynamicCollection } from '@vertesia/common';
1
+ import type { Collection, ContentObjectTypeCatalogEntry, DynamicCollection, JSONObject } from '@vertesia/common';
2
2
  import {
3
3
  Button,
4
4
  errorMessage,
@@ -59,6 +59,10 @@ interface DocumentUploadModalProps {
59
59
  /** Show only the type selection, used for type change operations */
60
60
  showTypeSelectionOnly?: boolean;
61
61
  allowFolders?: boolean;
62
+ /** Preselect a content type while preserving the normal type chooser. */
63
+ initialTypeId?: string;
64
+ /** Properties applied to newly created objects from this upload. */
65
+ defaultProperties?: JSONObject;
62
66
  }
63
67
 
64
68
  /**
@@ -81,6 +85,8 @@ export function DocumentUploadModal({
81
85
  hideFileSelection = false,
82
86
  showTypeSelectionOnly = false,
83
87
  allowFolders = true,
88
+ initialTypeId,
89
+ defaultProperties,
84
90
  }: DocumentUploadModalProps) {
85
91
  const { client } = useUserSession();
86
92
  const { registry: typeRegistry } = useTypeRegistry();
@@ -222,7 +228,7 @@ export function DocumentUploadModal({
222
228
  // Always reset state first
223
229
  setProcessedFiles([]);
224
230
  setProcessingDone(false);
225
- setSelectedType(null);
231
+ setSelectedType(initialTypeId ? (typeRegistry?.getType(initialTypeId) ?? null) : null);
226
232
  setFileStatuses([]);
227
233
  setIsUploading(false);
228
234
  setUploadComplete(false);
@@ -243,7 +249,7 @@ export function DocumentUploadModal({
243
249
  // Create a new key to ensure the modal is fresh
244
250
  setModalKey(Date.now());
245
251
  }
246
- }, [isOpen, initialFiles, processFiles, resolvedTitle]);
252
+ }, [initialFiles, initialTypeId, isOpen, processFiles, resolvedTitle, typeRegistry]);
247
253
 
248
254
  // Complete cleanup when modal closes
249
255
  const handleClose = () => {
@@ -415,6 +421,7 @@ export function DocumentUploadModal({
415
421
  content: fileInfo.file,
416
422
  location:
417
423
  fileInfo.location || fileInfo.file.webkitRelativePath || fileInfo.name,
424
+ properties: defaultProperties,
418
425
  },
419
426
  {
420
427
  collection_id: collectionId,
@@ -1,4 +1,4 @@
1
- import type { ComplexSearchPayload, ContentObjectItem, FindPayload } from '@vertesia/common';
1
+ import type { ComplexSearchPayload, FindPayload } from '@vertesia/common';
2
2
  import { errorMessage, useToast } from '@vertesia/ui/core';
3
3
  import { i18nInstance, NAMESPACE } from '@vertesia/ui/i18n';
4
4
  import { useUserSession } from '@vertesia/ui/session';
@@ -7,6 +7,11 @@ import { Md5 } from 'ts-md5';
7
7
 
8
8
  const t = i18nInstance.getFixedT(null, NAMESPACE);
9
9
 
10
+ interface ExistingHashMatch {
11
+ id: string;
12
+ content?: { etag?: string };
13
+ }
14
+
10
15
  /**
11
16
  * Types of actions that can be taken with a file
12
17
  */
@@ -140,20 +145,24 @@ export function useSmartFileUploadProcessing() {
140
145
  'content.etag': { $in: hashes },
141
146
  };
142
147
 
143
- let res: Array<Pick<ContentObjectItem, 'id' | 'content'>>;
148
+ let res: ExistingHashMatch[];
144
149
 
145
150
  if (limitToCollectionId) {
146
151
  const payload: ComplexSearchPayload = {
147
152
  query: { match: query },
148
153
  select: 'id content.etag',
149
154
  };
150
- res = (await client.store.collections.searchMembers(limitToCollectionId, payload)).results;
155
+ res = (
156
+ await client.store.collections.searchMembers(limitToCollectionId, payload)
157
+ ).results.filter((doc): doc is ExistingHashMatch => typeof doc.id === 'string');
151
158
  } else {
152
- const payload: FindPayload = {
159
+ const payload = {
153
160
  query,
154
161
  select: 'id content.etag',
155
- };
156
- res = await client.store.objects.find(payload);
162
+ } satisfies FindPayload & { select: string };
163
+ res = (await client.store.objects.find(payload)).flatMap((doc) =>
164
+ typeof doc.id === 'string' ? [{ id: doc.id, content: doc.content }] : [],
165
+ );
157
166
  }
158
167
 
159
168
  for (const doc of res) {
@@ -3,11 +3,8 @@ import { Button, CopyButton, Table, TBody, THead, VTooltip } from '@vertesia/ui/
3
3
  import { useUITranslation } from '@vertesia/ui/i18n';
4
4
  import { useNavigate } from '@vertesia/ui/router';
5
5
  import clsx from 'clsx';
6
- import dayjs from 'dayjs';
7
- import relativeTime from 'dayjs/plugin/relativeTime';
8
6
  import { Filter } from 'lucide-react';
9
-
10
- dayjs.extend(relativeTime);
7
+ import dayjs from '../../../core/utils/dayjs.js';
11
8
 
12
9
  const ACTION_BTN_CLASS =
13
10
  'h-6 w-6 p-0 opacity-0 group-hover/field:opacity-100 text-muted hover:text-foreground transition-opacity shrink-0';
@@ -345,7 +345,17 @@ export function IntakePolicyEditor({
345
345
  onSaveProp ??
346
346
  (objectType
347
347
  ? (next: ContentTypeIntakePolicy) =>
348
- store.types.update(objectType.id, { intake: next }).then((response) => response.intake)
348
+ store.types
349
+ .update(objectType.id, {
350
+ intake: next,
351
+ ...(objectType.edit_revision === undefined
352
+ ? {}
353
+ : { expected_edit_revision: objectType.edit_revision }),
354
+ })
355
+ .then((response) => {
356
+ objectType.edit_revision = response.edit_revision;
357
+ return response.intake;
358
+ })
349
359
  : undefined);
350
360
  if (!persist) {
351
361
  return;
@@ -35,8 +35,12 @@ export function ObjectSchemaEditor({ objectType, onSchemaUpdate, readonly = fals
35
35
 
36
36
  setUpdating(true);
37
37
  store.types
38
- .update(objectType.id, { object_schema: schema.schema })
39
- .then(() => {
38
+ .update(objectType.id, {
39
+ object_schema: schema.schema,
40
+ ...(objectType.edit_revision === undefined ? {} : { expected_edit_revision: objectType.edit_revision }),
41
+ })
42
+ .then((response) => {
43
+ objectType.edit_revision = response.edit_revision;
40
44
  onSchemaUpdate(schema);
41
45
  toast({
42
46
  status: 'success',
@@ -62,9 +62,11 @@ export function TableLayoutEditor({ objectType, onLayoutUpdate, readonly = false
62
62
  setUpdating(true);
63
63
  store.types
64
64
  .update(objectType.id, {
65
+ ...(objectType.edit_revision === undefined ? {} : { expected_edit_revision: objectType.edit_revision }),
65
66
  table_layout,
66
67
  })
67
68
  .then((response) => {
69
+ objectType.edit_revision = response.edit_revision;
68
70
  toast({
69
71
  status: 'success',
70
72
  title: t('store.tableLayoutUpdated'),
@@ -68,6 +68,16 @@ describe('UserInfo', () => {
68
68
  expect(retrieveUser).toHaveBeenCalledTimes(1);
69
69
  });
70
70
 
71
+ it('renders a service account title from a ref that has no nested type', async () => {
72
+ render(
73
+ <I18nProvider lng="en">
74
+ <UserInfo userRef="service_account:66b27abd91cf39f93cdc1335" showTitle />
75
+ </I18nProvider>,
76
+ );
77
+
78
+ expect(await screen.findByText(/~dc1335/)).toBeDefined();
79
+ });
80
+
71
81
  it('renders a missing group as an unknown principal and caches the 404', async () => {
72
82
  const error = Object.assign(new Error('Not Found'), { status: 404 });
73
83
  retrieveGroup.mockRejectedValueOnce(error);
@@ -104,16 +104,11 @@ interface ServiceInfoProps extends InfoProps {
104
104
  }
105
105
  function ServiceAccountAvatar({ accountId, showTitle = false, size = 'md' }: ServiceInfoProps) {
106
106
  const { t } = useUITranslation();
107
- const _type = accountId.split(':')[0];
108
- const _accountId = accountId.split(':')[1];
109
107
  const description = (
110
108
  <>
111
109
  <div>{t('user.serviceAccountDescription')}</div>
112
110
  <div className="text-muted text-sm">
113
- <span className="font-semibold">Type:</span> {_type}
114
- </div>
115
- <div className="text-muted text-sm">
116
- <span className="font-semibold">ID:</span> {_accountId}
111
+ <span className="font-semibold">ID:</span> {accountId}
117
112
  </div>
118
113
  </>
119
114
  );
@@ -124,7 +119,7 @@ function ServiceAccountAvatar({ accountId, showTitle = false, size = 'md' }: Ser
124
119
  <Avatar src="/cloud.svg" name="SA" color="bg-amber-500" className="px-[5px] text-white" size={size} />
125
120
  {showTitle && (
126
121
  <div className="text-sm font-semibold ps-2 truncate">
127
- {t('user.serviceAccount')} : ~{_accountId.slice(-6)}
122
+ {t('user.serviceAccount')} : ~{accountId.slice(-6)}
128
123
  </div>
129
124
  )}
130
125
  </div>
@@ -0,0 +1,80 @@
1
+ import { cleanup, screen } from '@testing-library/react';
2
+ import type { VertesiaClient } from '@vertesia/client';
3
+ import { ContentObjectStatus, type ViewExecutionResult, type ViewHit } from '@vertesia/common';
4
+ import { afterEach, describe, expect, it, vi } from 'vitest';
5
+ import { renderWithProviders } from '../../__tests__/test-utils.js';
6
+ import type { ViewSelectionController } from './types.js';
7
+ import { ViewActionsProvider, ViewActionsToolbar } from './ViewActions.js';
8
+
9
+ const hit: ViewHit = {
10
+ id: 'document-1',
11
+ document: {
12
+ id: 'document-1',
13
+ name: 'Invoice',
14
+ created_at: '2026-01-01T00:00:00.000Z',
15
+ created_by: 'user-1',
16
+ updated_at: '2026-01-01T00:00:00.000Z',
17
+ updated_by: 'user-1',
18
+ location: '/Invoices',
19
+ status: ContentObjectStatus.completed,
20
+ properties: {},
21
+ revision: { root: 'document-1', head: true },
22
+ },
23
+ };
24
+
25
+ const result: ViewExecutionResult = {
26
+ view: 'invoices',
27
+ revision: 1,
28
+ definition: {
29
+ name: 'Invoices',
30
+ results: {
31
+ default_display: 'list',
32
+ selection: { mode: 'multiple' },
33
+ actions: { include_defaults: true },
34
+ displays: [{ id: 'list', label: 'List', type: 'list', title: { field: 'name' } }],
35
+ },
36
+ },
37
+ display: 'list',
38
+ search: { requested_mode: 'browse', applied_mode: 'browse', warnings: [] },
39
+ hits: [hit],
40
+ total: 1,
41
+ navigation: {},
42
+ took: 1,
43
+ };
44
+
45
+ const selection: ViewSelectionController = {
46
+ mode: 'multiple',
47
+ selectAll: false,
48
+ selectedIds: [hit.id],
49
+ selectedHits: [hit],
50
+ isSelected: (id) => id === hit.id,
51
+ toggle: vi.fn(),
52
+ togglePage: vi.fn(),
53
+ clear: vi.fn(),
54
+ };
55
+
56
+ describe('ViewActionsProvider', () => {
57
+ afterEach(() => {
58
+ cleanup();
59
+ vi.clearAllMocks();
60
+ });
61
+
62
+ it('enables the standard export and permission-gated delete actions', () => {
63
+ renderWithProviders(
64
+ <ViewActionsProvider
65
+ definition={result.definition}
66
+ request={{}}
67
+ result={result}
68
+ selection={selection}
69
+ client={{} as VertesiaClient}
70
+ canDelete
71
+ refresh={vi.fn()}
72
+ >
73
+ <ViewActionsToolbar selection={selection} page={result.hits} />
74
+ </ViewActionsProvider>,
75
+ );
76
+
77
+ expect(screen.getByRole('button', { name: /export/i })).not.toBeNull();
78
+ expect(screen.getByRole('button', { name: /delete/i })).not.toBeNull();
79
+ });
80
+ });
@@ -0,0 +1,352 @@
1
+ import type { VertesiaClient } from '@vertesia/client';
2
+ import type {
3
+ ExecuteViewRequest,
4
+ ViewActionConfiguration,
5
+ ViewExecutionDefinition,
6
+ ViewExecutionResult,
7
+ ViewHit,
8
+ } from '@vertesia/common';
9
+ import {
10
+ Button,
11
+ Checkbox,
12
+ ConfirmModal,
13
+ Popover,
14
+ PopoverContent,
15
+ PopoverTrigger,
16
+ SelectList,
17
+ useToast,
18
+ } from '@vertesia/ui/core';
19
+ import { useUITranslation } from '@vertesia/ui/i18n';
20
+ import { Download, EllipsisVertical, Trash2, X } from 'lucide-react';
21
+ import { createContext, type ReactNode, useCallback, useContext, useId, useMemo, useRef, useState } from 'react';
22
+ import { ExportPropertiesModal } from '../store/objects/ExportPropertiesModal.js';
23
+ import type {
24
+ ViewActionContext,
25
+ ViewActionContribution,
26
+ ViewExperienceContributions,
27
+ ViewSelectionController,
28
+ } from './types.js';
29
+
30
+ interface PendingAction {
31
+ action: ViewActionConfiguration;
32
+ hits: ViewHit[];
33
+ }
34
+
35
+ interface ViewActionsRuntime {
36
+ actions: ViewActionConfiguration[];
37
+ runningActionId?: string;
38
+ run: (action: ViewActionConfiguration, hits: ViewHit[]) => void;
39
+ }
40
+
41
+ const ViewActionsContext = createContext<ViewActionsRuntime | undefined>(undefined);
42
+
43
+ export function useViewActions(): ViewActionsRuntime | undefined {
44
+ return useContext(ViewActionsContext);
45
+ }
46
+
47
+ interface ViewActionsProviderProps {
48
+ children: ReactNode;
49
+ definition: ViewExecutionDefinition;
50
+ request: ExecuteViewRequest;
51
+ result: ViewExecutionResult;
52
+ selection?: ViewSelectionController;
53
+ contributions?: ViewExperienceContributions;
54
+ client?: VertesiaClient;
55
+ canDelete: boolean;
56
+ refresh: () => Promise<void>;
57
+ }
58
+
59
+ function selectionMatches(action: ViewActionConfiguration, hits: ViewHit[]): boolean {
60
+ const requirement = action.requires_selection ?? (action.placement === 'toolbar' ? 'none' : 'any');
61
+ if (requirement === 'none') return true;
62
+ if (requirement === 'single') return hits.length === 1;
63
+ if (requirement === 'multiple') return hits.length > 1;
64
+ return hits.length > 0;
65
+ }
66
+
67
+ function triggerDownload(response: { type: string; name: string; data: string }): void {
68
+ const url = window.URL.createObjectURL(new Blob([response.data], { type: response.type }));
69
+ const anchor = document.createElement('a');
70
+ anchor.download = response.name;
71
+ anchor.href = url;
72
+ anchor.click();
73
+ window.setTimeout(() => window.URL.revokeObjectURL(url), 0);
74
+ }
75
+
76
+ export function ViewActionsProvider({
77
+ children,
78
+ definition,
79
+ request,
80
+ result,
81
+ selection,
82
+ contributions,
83
+ client,
84
+ canDelete,
85
+ refresh,
86
+ }: ViewActionsProviderProps) {
87
+ const { t } = useUITranslation();
88
+ const toast = useToast();
89
+ const [pending, setPending] = useState<PendingAction>();
90
+ const [exportHits, setExportHits] = useState<ViewHit[]>();
91
+ const [isExporting, setIsExporting] = useState(false);
92
+ const [runningActionId, setRunningActionId] = useState<string>();
93
+ const runningActionRef = useRef(false);
94
+ const actionsConfiguration = definition.results?.actions;
95
+
96
+ const baseContext = useMemo<Omit<ViewActionContext, 'action' | 'hits'>>(
97
+ () => ({
98
+ definition,
99
+ request,
100
+ result,
101
+ refresh,
102
+ clearSelection: () => selection?.clear(),
103
+ }),
104
+ [definition, refresh, request, result, selection],
105
+ );
106
+
107
+ const actions = useMemo(() => {
108
+ const configured = (actionsConfiguration?.items ?? []).filter((action) => {
109
+ const contribution = contributions?.actions?.[action.handler];
110
+ return contribution !== undefined && (contribution.isAvailable?.(baseContext) ?? true);
111
+ });
112
+ if (!selection || actionsConfiguration?.include_defaults === false || !client) return configured;
113
+
114
+ const excluded = new Set(actionsConfiguration?.exclude_defaults ?? []);
115
+ const defaults: ViewActionConfiguration[] = [];
116
+ if (!excluded.has('export')) {
117
+ defaults.push({
118
+ id: 'export',
119
+ label: t('store.actions.exportProperties'),
120
+ handler: 'export',
121
+ placement: 'selection',
122
+ requires_selection: 'any',
123
+ });
124
+ }
125
+ if (canDelete && !excluded.has('delete')) {
126
+ defaults.push({
127
+ id: 'delete',
128
+ label: t('store.actions.delete'),
129
+ handler: 'delete',
130
+ placement: 'selection',
131
+ requires_selection: 'any',
132
+ destructive: true,
133
+ confirm: true,
134
+ });
135
+ }
136
+ return [...defaults, ...configured];
137
+ }, [actionsConfiguration, baseContext, canDelete, client, contributions?.actions, selection, t]);
138
+
139
+ const execute = useCallback(
140
+ async ({ action, hits }: PendingAction) => {
141
+ if (runningActionRef.current) return;
142
+ runningActionRef.current = true;
143
+ setRunningActionId(action.id);
144
+ try {
145
+ if (action.handler === 'delete') {
146
+ if (!client) return;
147
+ const response = await client.store.objects.delete(hits.map((hit) => hit.id));
148
+ toast({
149
+ status: response.failed.length > 0 ? 'warning' : 'success',
150
+ title: t('view.deletedObjects', { count: response.deleted }),
151
+ });
152
+ selection?.clear();
153
+ await refresh();
154
+ return;
155
+ }
156
+
157
+ const contribution: ViewActionContribution | undefined = contributions?.actions?.[action.handler];
158
+ if (!contribution) return;
159
+ await contribution.run({ ...baseContext, action, hits });
160
+ } catch (error: unknown) {
161
+ console.error('View action failed:', error);
162
+ toast({
163
+ status: 'error',
164
+ title: t('view.actionFailed'),
165
+ description: t('view.actionFailedDescription'),
166
+ });
167
+ } finally {
168
+ runningActionRef.current = false;
169
+ setRunningActionId(undefined);
170
+ setPending(undefined);
171
+ }
172
+ },
173
+ [baseContext, client, contributions?.actions, refresh, selection, t, toast],
174
+ );
175
+
176
+ const run = useCallback(
177
+ (action: ViewActionConfiguration, hits: ViewHit[]) => {
178
+ if (!selectionMatches(action, hits) || runningActionRef.current) return;
179
+ if (action.handler === 'export') {
180
+ setExportHits(hits);
181
+ return;
182
+ }
183
+ if (action.confirm) {
184
+ setPending({ action, hits });
185
+ return;
186
+ }
187
+ void execute({ action, hits });
188
+ },
189
+ [execute],
190
+ );
191
+
192
+ const closeExport = useCallback(
193
+ (format?: string | null) => {
194
+ if (!format || !exportHits?.length || !client) {
195
+ setExportHits(undefined);
196
+ return;
197
+ }
198
+ setIsExporting(true);
199
+ void client.store.objects
200
+ .exportProperties({ objectIds: exportHits.map((hit) => hit.id), type: format })
201
+ .then((response) => {
202
+ triggerDownload(response);
203
+ toast({ status: 'success', title: t('store.actions.exportProperties') });
204
+ setExportHits(undefined);
205
+ })
206
+ .catch((error: unknown) => {
207
+ console.error('View export failed:', error);
208
+ toast({
209
+ status: 'error',
210
+ title: t('store.actions.errorExportProperties'),
211
+ description: t('view.actionFailedDescription'),
212
+ });
213
+ })
214
+ .finally(() => setIsExporting(false));
215
+ },
216
+ [client, exportHits, t, toast],
217
+ );
218
+
219
+ const value = useMemo<ViewActionsRuntime>(
220
+ () => ({ actions, runningActionId, run }),
221
+ [actions, run, runningActionId],
222
+ );
223
+
224
+ return (
225
+ <ViewActionsContext.Provider value={value}>
226
+ {children}
227
+ <ExportPropertiesModal
228
+ isOpen={exportHits !== undefined}
229
+ isExporting={isExporting}
230
+ onClose={closeExport}
231
+ allowExportAll={false}
232
+ />
233
+ <ConfirmModal
234
+ isOpen={pending !== undefined}
235
+ title={pending?.action.label ?? t('modal.confirm')}
236
+ content={t('view.confirmAction', {
237
+ action: pending?.action.label ?? '',
238
+ count: pending?.hits.length ?? 0,
239
+ })}
240
+ isLoading={runningActionId !== undefined}
241
+ onConfirm={() => {
242
+ if (pending) void execute(pending);
243
+ }}
244
+ onCancel={() => setPending(undefined)}
245
+ confirmationValue={pending?.action.handler === 'delete' ? 'delete' : undefined}
246
+ confirmationLabel={pending?.action.handler === 'delete' ? t('view.typeDeleteToConfirm') : undefined}
247
+ confirmationPlaceholder={pending?.action.handler === 'delete' ? 'delete' : undefined}
248
+ />
249
+ </ViewActionsContext.Provider>
250
+ );
251
+ }
252
+
253
+ export function ViewActionsToolbar({
254
+ selection,
255
+ page,
256
+ showSelectPage = false,
257
+ }: {
258
+ selection?: ViewSelectionController;
259
+ page: ViewHit[];
260
+ showSelectPage?: boolean;
261
+ }) {
262
+ const { t } = useUITranslation();
263
+ const runtime = useViewActions();
264
+ const selectPageId = useId();
265
+ if (!runtime) return null;
266
+ const selected = selection?.selectedHits ?? [];
267
+ const selectedOnPage = selection ? page.filter((hit) => selection.isSelected(hit.id)).length : 0;
268
+ const allOnPageSelected = page.length > 0 && selectedOnPage === page.length;
269
+ const canSelectPage = showSelectPage && selection?.selectAll && page.length > 0;
270
+ const actions = runtime.actions.filter(
271
+ (action) =>
272
+ ((action.placement ?? 'selection') === 'toolbar' ||
273
+ ((action.placement ?? 'selection') === 'selection' && selected.length > 0)) &&
274
+ selectionMatches(action, selected),
275
+ );
276
+ if (actions.length === 0 && selected.length === 0 && !canSelectPage) return null;
277
+
278
+ return (
279
+ <div className="flex flex-wrap items-center gap-2">
280
+ {canSelectPage && selection && (
281
+ <div className="flex items-center gap-2">
282
+ <Checkbox
283
+ id={selectPageId}
284
+ checked={allOnPageSelected ? true : selectedOnPage > 0 ? 'indeterminate' : false}
285
+ onCheckedChange={(checked) => selection.togglePage(page, checked === true)}
286
+ />
287
+ <label htmlFor={selectPageId} className="text-sm text-muted">
288
+ {t('view.selectPage')}
289
+ </label>
290
+ </div>
291
+ )}
292
+ {selected.length > 0 && (
293
+ <>
294
+ <span className="text-sm text-muted">{t('view.selectedCount', { count: selected.length })}</span>
295
+ <Button
296
+ type="button"
297
+ variant="ghost"
298
+ size="icon"
299
+ aria-label={t('view.clearSelection')}
300
+ onClick={selection?.clear}
301
+ >
302
+ <X className="size-4" />
303
+ </Button>
304
+ </>
305
+ )}
306
+ {actions.map((action) => (
307
+ <Button
308
+ key={action.id}
309
+ type="button"
310
+ variant={action.destructive ? 'destructive' : 'outline'}
311
+ size="sm"
312
+ disabled={runtime.runningActionId !== undefined}
313
+ onClick={() => runtime.run(action, selected)}
314
+ >
315
+ {action.handler === 'export' && <Download className="size-4" />}
316
+ {action.handler === 'delete' && <Trash2 className="size-4" />}
317
+ {action.label}
318
+ </Button>
319
+ ))}
320
+ </div>
321
+ );
322
+ }
323
+
324
+ export function ViewRowActions({ hit }: { hit: ViewHit }) {
325
+ const { t } = useUITranslation();
326
+ const runtime = useViewActions();
327
+ const actions = runtime?.actions.filter(
328
+ (action) => (action.placement ?? 'selection') === 'row' && selectionMatches(action, [hit]),
329
+ );
330
+ if (!runtime || !actions?.length) return null;
331
+
332
+ return (
333
+ <Popover>
334
+ <PopoverTrigger>
335
+ <Button type="button" variant="ghost" size="icon" aria-label={t('view.actions')}>
336
+ <EllipsisVertical className="size-4" />
337
+ </Button>
338
+ </PopoverTrigger>
339
+ <PopoverContent className="w-52 p-1" align="end" sideOffset={6}>
340
+ <SelectList
341
+ options={actions}
342
+ optionLayout={(action) => ({
343
+ label: action.label,
344
+ className: action.destructive ? 'text-destructive' : undefined,
345
+ })}
346
+ onChange={(action) => runtime.run(action, [hit])}
347
+ noCheck
348
+ />
349
+ </PopoverContent>
350
+ </Popover>
351
+ );
352
+ }