@invect/ui 0.0.1

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 (419) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/Invect-CWpIwZ5F.js +92738 -0
  4. package/dist/Invect.d.ts +25 -0
  5. package/dist/InvectShell.d.ts +14 -0
  6. package/dist/api/agent-tools.api.d.ts +1 -0
  7. package/dist/api/client.d.ts +207 -0
  8. package/dist/api/credentials.api.d.ts +47 -0
  9. package/dist/api/executions.api.d.ts +43 -0
  10. package/dist/api/flows.api.d.ts +100 -0
  11. package/dist/api/index.d.ts +9 -0
  12. package/dist/api/node-data.api.d.ts +66 -0
  13. package/dist/api/query-keys.d.ts +22 -0
  14. package/dist/api/triggers.api.d.ts +44 -0
  15. package/dist/api/types.d.ts +147 -0
  16. package/dist/api/use-flow-run-stream.d.ts +12 -0
  17. package/dist/assets/invect-branding.d.ts +4 -0
  18. package/dist/assets/provider-icons/index.d.ts +8 -0
  19. package/dist/babel-C9OtljFZ.js +9721 -0
  20. package/dist/components/PageLayout.d.ts +17 -0
  21. package/dist/components/chat/ChatInput.d.ts +17 -0
  22. package/dist/components/chat/ChatMessageList.d.ts +14 -0
  23. package/dist/components/chat/ChatModelSelector.d.ts +11 -0
  24. package/dist/components/chat/ChatPanel.d.ts +19 -0
  25. package/dist/components/chat/ChatPromptOverlay.d.ts +13 -0
  26. package/dist/components/chat/ChatProviderSelector.d.ts +9 -0
  27. package/dist/components/chat/ChatSettingsPanel.d.ts +11 -0
  28. package/dist/components/chat/InlineCredentialSetup.d.ts +9 -0
  29. package/dist/components/chat/MarkdownRenderer.d.ts +7 -0
  30. package/dist/components/chat/chat-memory.d.ts +21 -0
  31. package/dist/components/chat/chat.store.d.ts +416 -0
  32. package/dist/components/chat/index.d.ts +5 -0
  33. package/dist/components/chat/use-chat.d.ts +28 -0
  34. package/dist/components/credentials/CreateCredentialModal.d.ts +13 -0
  35. package/dist/components/credentials/CredentialDetailDialog.d.ts +17 -0
  36. package/dist/components/credentials/EditCredentialModal.d.ts +11 -0
  37. package/dist/components/credentials/OAuth2ConnectButton.d.ts +38 -0
  38. package/dist/components/credentials/OAuth2ProviderSelector.d.ts +15 -0
  39. package/dist/components/credentials/credential-utils.d.ts +12 -0
  40. package/dist/components/credentials/index.d.ts +9 -0
  41. package/dist/components/dashboard/FailedRunsAlert.d.ts +3 -0
  42. package/dist/components/dashboard/FlowCard.d.ts +7 -0
  43. package/dist/components/dashboard/RecentActivityTable.d.ts +9 -0
  44. package/dist/components/dashboard/StatCard.d.ts +10 -0
  45. package/dist/components/dashboard/index.d.ts +5 -0
  46. package/dist/components/dashboard/status-helpers.d.ts +5 -0
  47. package/dist/components/flow-editor/ActionsSidebar.d.ts +2 -0
  48. package/dist/components/flow-editor/FlowEditor.d.ts +21 -0
  49. package/dist/components/flow-editor/FlowHeader.d.ts +9 -0
  50. package/dist/components/flow-editor/FlowLayout.d.ts +24 -0
  51. package/dist/components/flow-editor/ModeSwitcher.d.ts +7 -0
  52. package/dist/components/flow-editor/NodeSidebar.d.ts +24 -0
  53. package/dist/components/flow-editor/RunControls.d.ts +12 -0
  54. package/dist/components/flow-editor/ToolConfigPanel.d.ts +16 -0
  55. package/dist/components/flow-editor/ValidationPanel.d.ts +5 -0
  56. package/dist/components/flow-editor/flow-editor.store.d.ts +1 -0
  57. package/dist/components/flow-editor/index.d.ts +6 -0
  58. package/dist/components/flow-editor/inline-edit.d.ts +10 -0
  59. package/dist/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.d.ts +26 -0
  60. package/dist/components/flow-editor/node-config-panel/CredentialCombobox.d.ts +21 -0
  61. package/dist/components/flow-editor/node-config-panel/CredentialsSection.d.ts +19 -0
  62. package/dist/components/flow-editor/node-config-panel/DroppableInput.d.ts +20 -0
  63. package/dist/components/flow-editor/node-config-panel/DynamicSelectField.d.ts +22 -0
  64. package/dist/components/flow-editor/node-config-panel/JsonPreviewPanel.d.ts +25 -0
  65. package/dist/components/flow-editor/node-config-panel/NodeConfigPanel.d.ts +14 -0
  66. package/dist/components/flow-editor/node-config-panel/NodeConfigPanelHeader.d.ts +15 -0
  67. package/dist/components/flow-editor/node-config-panel/ParametersSection.d.ts +16 -0
  68. package/dist/components/flow-editor/node-config-panel/SearchableSelectField.d.ts +17 -0
  69. package/dist/components/flow-editor/node-config-panel/SwitchCasesField.d.ts +18 -0
  70. package/dist/components/flow-editor/node-config-panel/hooks/index.d.ts +2 -0
  71. package/dist/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.d.ts +24 -0
  72. package/dist/components/flow-editor/node-config-panel/hooks/use-node-execution.d.ts +46 -0
  73. package/dist/components/flow-editor/node-config-panel/hooks/use-upstream-slots.d.ts +16 -0
  74. package/dist/components/flow-editor/node-config-panel/panels/AgentToolsPanel.d.ts +18 -0
  75. package/dist/components/flow-editor/node-config-panel/panels/ConfigurationPanel.d.ts +49 -0
  76. package/dist/components/flow-editor/node-config-panel/panels/DataMapperPane.d.ts +40 -0
  77. package/dist/components/flow-editor/node-config-panel/panels/InputPanel.d.ts +49 -0
  78. package/dist/components/flow-editor/node-config-panel/panels/OutputPanel.d.ts +7 -0
  79. package/dist/components/flow-editor/node-config-panel/panels/index.d.ts +4 -0
  80. package/dist/components/flow-editor/node-config-panel/types.d.ts +19 -0
  81. package/dist/components/flow-editor/node-config-panel/use-node-config-panel-store.d.ts +49 -0
  82. package/dist/components/flow-editor/node-config-panel/use-node-config-state.d.ts +26 -0
  83. package/dist/components/flow-editor/node-config-panel/use-run-node.d.ts +16 -0
  84. package/dist/components/flow-editor/node-config-panel/utils.d.ts +9 -0
  85. package/dist/components/flow-editor/serialize-to-sdk.d.ts +20 -0
  86. package/dist/components/flow-editor/toolbar-context.d.ts +2 -0
  87. package/dist/components/flow-editor/use-copy-paste.d.ts +7 -0
  88. package/dist/components/flow-editor/use-copy-paste.types.d.ts +38 -0
  89. package/dist/components/flow-editor/use-flow-editor.d.ts +44 -0
  90. package/dist/components/flow-runs-table/FlowRunsTable.d.ts +6 -0
  91. package/dist/components/flow-runs-table/index.d.ts +1 -0
  92. package/dist/components/flow-viewer/FlowRunsView.d.ts +7 -0
  93. package/dist/components/flow-viewer/FlowStatusView.d.ts +21 -0
  94. package/dist/components/flow-viewer/RunSelector.d.ts +13 -0
  95. package/dist/components/flow-viewer/RunsSidebar.d.ts +14 -0
  96. package/dist/components/flow-viewer/agent-tool-executions-list.d.ts +7 -0
  97. package/dist/components/flow-viewer/index.d.ts +1 -0
  98. package/dist/components/flow-viewer/logs-panel.d.ts +18 -0
  99. package/dist/components/flow-viewer/use-execution-log-data.d.ts +113 -0
  100. package/dist/components/graph/BatchFlowEdge.d.ts +33 -0
  101. package/dist/components/graph/LayoutSelector.d.ts +9 -0
  102. package/dist/components/graph/index.d.ts +47 -0
  103. package/dist/components/graph/styleUtils.d.ts +124 -0
  104. package/dist/components/nodes/AgentConfigPanel.d.ts +24 -0
  105. package/dist/components/nodes/AgentNode.d.ts +8 -0
  106. package/dist/components/nodes/AgentToolsBox.d.ts +41 -0
  107. package/dist/components/nodes/NodeAppendix.d.ts +19 -0
  108. package/dist/components/nodes/NodeStatusIndicator.d.ts +30 -0
  109. package/dist/components/nodes/NodeViewContext.d.ts +18 -0
  110. package/dist/components/nodes/ToolParamField.d.ts +28 -0
  111. package/dist/components/nodes/ToolSelectorModal.d.ts +80 -0
  112. package/dist/components/nodes/ToolSelectorParts.d.ts +30 -0
  113. package/dist/components/nodes/UniversalNode.d.ts +2 -0
  114. package/dist/components/nodes/createContextAwareNodes.d.ts +6 -0
  115. package/dist/components/nodes/index.d.ts +22 -0
  116. package/dist/components/nodes/nodeRegistry.d.ts +13 -0
  117. package/dist/components/nodes/withNodeContext.d.ts +7 -0
  118. package/dist/components/shared/InvectLoader.d.ts +8 -0
  119. package/dist/components/shared/InvectLogo.d.ts +9 -0
  120. package/dist/components/shared/ProviderIcon.d.ts +23 -0
  121. package/dist/components/side-menu/side-menu.d.ts +4 -0
  122. package/dist/components/sidebar/BaseSidebar.d.ts +17 -0
  123. package/dist/components/sidebar/index.d.ts +1 -0
  124. package/dist/components/triggers/CronPreview.d.ts +12 -0
  125. package/dist/components/triggers/index.d.ts +1 -0
  126. package/dist/components/ui/alert-dialog.d.ts +18 -0
  127. package/dist/components/ui/badge.d.ts +9 -0
  128. package/dist/components/ui/button.d.ts +13 -0
  129. package/dist/components/ui/card.d.ts +9 -0
  130. package/dist/components/ui/codemirror-js-editor.d.ts +25 -0
  131. package/dist/components/ui/codemirror-json-editor.d.ts +18 -0
  132. package/dist/components/ui/codemirror-nunjucks-editor.d.ts +13 -0
  133. package/dist/components/ui/codemirror-vscode-theme.d.ts +24 -0
  134. package/dist/components/ui/collapsible.d.ts +6 -0
  135. package/dist/components/ui/command.d.ts +18 -0
  136. package/dist/components/ui/dialog.d.ts +18 -0
  137. package/dist/components/ui/dropdown-menu.d.ts +25 -0
  138. package/dist/components/ui/empty-state.d.ts +21 -0
  139. package/dist/components/ui/input.d.ts +3 -0
  140. package/dist/components/ui/label.d.ts +4 -0
  141. package/dist/components/ui/popover.d.ts +10 -0
  142. package/dist/components/ui/resizable.d.ts +8 -0
  143. package/dist/components/ui/scroll-area.d.ts +5 -0
  144. package/dist/components/ui/select.d.ts +18 -0
  145. package/dist/components/ui/separator.d.ts +4 -0
  146. package/dist/components/ui/slider.d.ts +4 -0
  147. package/dist/components/ui/switch.d.ts +3 -0
  148. package/dist/components/ui/table.d.ts +10 -0
  149. package/dist/components/ui/textarea.d.ts +3 -0
  150. package/dist/components/ui/tooltip.d.ts +7 -0
  151. package/dist/components/ui/tree-view.d.ts +107 -0
  152. package/dist/contexts/AgentToolCallbacksContext.d.ts +23 -0
  153. package/dist/contexts/ApiContext.d.ts +11 -0
  154. package/dist/contexts/FlowDataContext.d.ts +9 -0
  155. package/dist/contexts/NodeRegistryContext.d.ts +14 -0
  156. package/dist/contexts/PluginRegistryContext.d.ts +39 -0
  157. package/dist/contexts/ThemeProvider.d.ts +18 -0
  158. package/dist/contexts/ValidationContext.d.ts +22 -0
  159. package/dist/demo/DemoInvect.d.ts +11 -0
  160. package/dist/demo/FlowViewer.d.ts +31 -0
  161. package/dist/demo/demo-api-client.d.ts +33 -0
  162. package/dist/demo/index.d.ts +6 -0
  163. package/dist/demo/sample-data.d.ts +1538 -0
  164. package/dist/demo.d.ts +2 -0
  165. package/dist/demo.js +2774 -0
  166. package/dist/estree-ClbRfS-1.js +7076 -0
  167. package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
  168. package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  169. package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
  170. package/dist/fonts/iosevka-latin-400-normal.woff2 +0 -0
  171. package/dist/hooks/index.d.ts +1 -0
  172. package/dist/hooks/use-document-title.d.ts +1 -0
  173. package/dist/hooks/use-flow-data.d.ts +22 -0
  174. package/dist/hooks/use-invect-portal-class.d.ts +21 -0
  175. package/dist/hooks/useFlowEditorStore.d.ts +1 -0
  176. package/dist/index.css +3 -0
  177. package/dist/index.d.ts +22 -0
  178. package/dist/index.js +717 -0
  179. package/dist/lib/utils.d.ts +2 -0
  180. package/dist/prettier.d.ts +13 -0
  181. package/dist/routes/all-flow-runs.d.ts +5 -0
  182. package/dist/routes/credentials.d.ts +5 -0
  183. package/dist/routes/flow-route-layout.d.ts +19 -0
  184. package/dist/routes/flow-runs.d.ts +5 -0
  185. package/dist/routes/flow.d.ts +5 -0
  186. package/dist/routes/home.d.ts +5 -0
  187. package/dist/services/index.d.ts +1 -0
  188. package/dist/standalone-C3Df7W52.js +3463 -0
  189. package/dist/stores/executionViewStore.d.ts +64 -0
  190. package/dist/stores/flow-editor.store.d.ts +137 -0
  191. package/dist/stores/flowEditorStore.d.ts +1 -0
  192. package/dist/stores/index.d.ts +2 -0
  193. package/dist/stores/uiStore.d.ts +45 -0
  194. package/dist/types/agent-tools.types.d.ts +53 -0
  195. package/dist/types/index.d.ts +2 -0
  196. package/dist/types/node-definition.types.d.ts +85 -0
  197. package/dist/types/plugin.types.d.ts +100 -0
  198. package/dist/utils/credentialBranding.d.ts +8 -0
  199. package/dist/utils/credentialFiltering.d.ts +20 -0
  200. package/dist/utils/flowTransformations.d.ts +16 -0
  201. package/dist/utils/layoutUtils.d.ts +23 -0
  202. package/dist/utils/nodeReferenceUtils.d.ts +37 -0
  203. package/dist/vendor.d.ts +5 -0
  204. package/package.json +130 -0
  205. package/src/.DS_Store +0 -0
  206. package/src/Invect.tsx +229 -0
  207. package/src/InvectShell.tsx +55 -0
  208. package/src/api/agent-tools.api.ts +23 -0
  209. package/src/api/client.ts +899 -0
  210. package/src/api/credentials.api.ts +197 -0
  211. package/src/api/executions.api.ts +228 -0
  212. package/src/api/flows.api.ts +195 -0
  213. package/src/api/index.ts +17 -0
  214. package/src/api/node-data.api.ts +167 -0
  215. package/src/api/query-keys.ts +44 -0
  216. package/src/api/triggers.api.ts +120 -0
  217. package/src/api/types.ts +212 -0
  218. package/src/api/use-flow-run-stream.ts +206 -0
  219. package/src/app.css +560 -0
  220. package/src/assets/.DS_Store +0 -0
  221. package/src/assets/favicon.ico +0 -0
  222. package/src/assets/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
  223. package/src/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  224. package/src/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
  225. package/src/assets/fonts/iosevka-latin-400-normal.woff2 +0 -0
  226. package/src/assets/invect-branding.ts +51 -0
  227. package/src/assets/provider-icons/anthropic.svg +1 -0
  228. package/src/assets/provider-icons/anthropic_light.svg +1 -0
  229. package/src/assets/provider-icons/github.svg +1 -0
  230. package/src/assets/provider-icons/github_light.svg +1 -0
  231. package/src/assets/provider-icons/gmail.svg +1 -0
  232. package/src/assets/provider-icons/google_calendar.svg +1 -0
  233. package/src/assets/provider-icons/google_docs.svg +1 -0
  234. package/src/assets/provider-icons/google_drive.svg +1 -0
  235. package/src/assets/provider-icons/google_sheets.svg +1 -0
  236. package/src/assets/provider-icons/index.ts +55 -0
  237. package/src/assets/provider-icons/linear.svg +1 -0
  238. package/src/assets/provider-icons/openai.svg +1 -0
  239. package/src/assets/provider-icons/postgres.svg +1 -0
  240. package/src/assets/provider-icons/slack.svg +1 -0
  241. package/src/assets/small-loader-dark.svg +22 -0
  242. package/src/assets/small-loader-light.svg +22 -0
  243. package/src/assets/small.svg +7 -0
  244. package/src/components/.DS_Store +0 -0
  245. package/src/components/PageLayout.tsx +55 -0
  246. package/src/components/chat/ChatInput.tsx +115 -0
  247. package/src/components/chat/ChatMessageList.tsx +788 -0
  248. package/src/components/chat/ChatModelSelector.tsx +208 -0
  249. package/src/components/chat/ChatPanel.tsx +243 -0
  250. package/src/components/chat/ChatPromptOverlay.tsx +150 -0
  251. package/src/components/chat/ChatProviderSelector.tsx +135 -0
  252. package/src/components/chat/ChatSettingsPanel.tsx +277 -0
  253. package/src/components/chat/InlineCredentialSetup.tsx +343 -0
  254. package/src/components/chat/MarkdownRenderer.tsx +140 -0
  255. package/src/components/chat/chat-memory.ts +88 -0
  256. package/src/components/chat/chat.store.ts +479 -0
  257. package/src/components/chat/index.ts +5 -0
  258. package/src/components/chat/use-chat.ts +473 -0
  259. package/src/components/credentials/CreateCredentialModal.tsx +609 -0
  260. package/src/components/credentials/CredentialDetailDialog.tsx +882 -0
  261. package/src/components/credentials/EditCredentialModal.tsx +399 -0
  262. package/src/components/credentials/OAuth2ConnectButton.tsx +288 -0
  263. package/src/components/credentials/OAuth2ProviderSelector.tsx +360 -0
  264. package/src/components/credentials/credential-utils.ts +99 -0
  265. package/src/components/credentials/index.ts +10 -0
  266. package/src/components/dashboard/FailedRunsAlert.tsx +67 -0
  267. package/src/components/dashboard/FlowCard.tsx +64 -0
  268. package/src/components/dashboard/RecentActivityTable.tsx +92 -0
  269. package/src/components/dashboard/StatCard.tsx +32 -0
  270. package/src/components/dashboard/index.ts +5 -0
  271. package/src/components/dashboard/status-helpers.tsx +102 -0
  272. package/src/components/flow-editor/ActionsSidebar.tsx +503 -0
  273. package/src/components/flow-editor/FlowEditor.tsx +1002 -0
  274. package/src/components/flow-editor/FlowHeader.tsx +87 -0
  275. package/src/components/flow-editor/FlowLayout.tsx +117 -0
  276. package/src/components/flow-editor/ModeSwitcher.tsx +49 -0
  277. package/src/components/flow-editor/NodeSidebar.tsx +343 -0
  278. package/src/components/flow-editor/RunControls.tsx +109 -0
  279. package/src/components/flow-editor/ToolConfigPanel.tsx +434 -0
  280. package/src/components/flow-editor/ValidationPanel.tsx +167 -0
  281. package/src/components/flow-editor/flow-editor.store.ts +2 -0
  282. package/src/components/flow-editor/index.ts +6 -0
  283. package/src/components/flow-editor/inline-edit.tsx +111 -0
  284. package/src/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.tsx +334 -0
  285. package/src/components/flow-editor/node-config-panel/CredentialCombobox.tsx +217 -0
  286. package/src/components/flow-editor/node-config-panel/CredentialsSection.tsx +154 -0
  287. package/src/components/flow-editor/node-config-panel/DroppableInput.tsx +45 -0
  288. package/src/components/flow-editor/node-config-panel/DynamicSelectField.tsx +223 -0
  289. package/src/components/flow-editor/node-config-panel/JsonPreviewPanel.tsx +134 -0
  290. package/src/components/flow-editor/node-config-panel/NodeConfigPanel.tsx +650 -0
  291. package/src/components/flow-editor/node-config-panel/NodeConfigPanelHeader.tsx +91 -0
  292. package/src/components/flow-editor/node-config-panel/ParametersSection.tsx +144 -0
  293. package/src/components/flow-editor/node-config-panel/SearchableSelectField.tsx +126 -0
  294. package/src/components/flow-editor/node-config-panel/SwitchCasesField.tsx +212 -0
  295. package/src/components/flow-editor/node-config-panel/hooks/index.ts +2 -0
  296. package/src/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.ts +284 -0
  297. package/src/components/flow-editor/node-config-panel/hooks/use-node-execution.ts +287 -0
  298. package/src/components/flow-editor/node-config-panel/hooks/use-upstream-slots.ts +310 -0
  299. package/src/components/flow-editor/node-config-panel/panels/AgentToolsPanel.tsx +837 -0
  300. package/src/components/flow-editor/node-config-panel/panels/ConfigurationPanel.tsx +383 -0
  301. package/src/components/flow-editor/node-config-panel/panels/DataMapperPane.tsx +456 -0
  302. package/src/components/flow-editor/node-config-panel/panels/InputPanel.tsx +338 -0
  303. package/src/components/flow-editor/node-config-panel/panels/OutputPanel.tsx +109 -0
  304. package/src/components/flow-editor/node-config-panel/panels/index.ts +4 -0
  305. package/src/components/flow-editor/node-config-panel/types.ts +20 -0
  306. package/src/components/flow-editor/node-config-panel/use-node-config-panel-store.ts +283 -0
  307. package/src/components/flow-editor/node-config-panel/use-node-config-state.ts +172 -0
  308. package/src/components/flow-editor/node-config-panel/use-run-node.ts +147 -0
  309. package/src/components/flow-editor/node-config-panel/utils.ts +73 -0
  310. package/src/components/flow-editor/serialize-to-sdk.ts +204 -0
  311. package/src/components/flow-editor/toolbar-context.ts +9 -0
  312. package/src/components/flow-editor/use-copy-paste.ts +575 -0
  313. package/src/components/flow-editor/use-copy-paste.types.ts +35 -0
  314. package/src/components/flow-editor/use-flow-editor.ts +241 -0
  315. package/src/components/flow-runs-table/FlowRunsTable.tsx +631 -0
  316. package/src/components/flow-runs-table/index.ts +1 -0
  317. package/src/components/flow-viewer/FlowRunsView.tsx +268 -0
  318. package/src/components/flow-viewer/FlowStatusView.tsx +351 -0
  319. package/src/components/flow-viewer/RunSelector.tsx +422 -0
  320. package/src/components/flow-viewer/RunsSidebar.tsx +125 -0
  321. package/src/components/flow-viewer/agent-tool-executions-list.tsx +298 -0
  322. package/src/components/flow-viewer/index.ts +1 -0
  323. package/src/components/flow-viewer/logs-panel.tsx +567 -0
  324. package/src/components/flow-viewer/use-execution-log-data.ts +374 -0
  325. package/src/components/graph/BatchFlowEdge.tsx +229 -0
  326. package/src/components/graph/LayoutSelector.tsx +42 -0
  327. package/src/components/graph/index.ts +61 -0
  328. package/src/components/graph/styleUtils.ts +375 -0
  329. package/src/components/nodes/.DS_Store +0 -0
  330. package/src/components/nodes/AgentConfigPanel.tsx +1033 -0
  331. package/src/components/nodes/AgentNode.tsx +298 -0
  332. package/src/components/nodes/AgentToolsBox.tsx +193 -0
  333. package/src/components/nodes/NodeAppendix.tsx +98 -0
  334. package/src/components/nodes/NodeStatusIndicator.tsx +74 -0
  335. package/src/components/nodes/NodeViewContext.tsx +45 -0
  336. package/src/components/nodes/ToolParamField.tsx +282 -0
  337. package/src/components/nodes/ToolSelectorModal.tsx +648 -0
  338. package/src/components/nodes/ToolSelectorParts.tsx +505 -0
  339. package/src/components/nodes/UniversalNode.tsx +356 -0
  340. package/src/components/nodes/createContextAwareNodes.ts +19 -0
  341. package/src/components/nodes/index.ts +45 -0
  342. package/src/components/nodes/nodeRegistry.ts +50 -0
  343. package/src/components/nodes/withNodeContext.tsx +55 -0
  344. package/src/components/shared/InvectLoader.tsx +59 -0
  345. package/src/components/shared/InvectLogo.tsx +59 -0
  346. package/src/components/shared/ProviderIcon.tsx +115 -0
  347. package/src/components/side-menu/side-menu.tsx +267 -0
  348. package/src/components/sidebar/BaseSidebar.tsx +148 -0
  349. package/src/components/sidebar/index.ts +1 -0
  350. package/src/components/triggers/CronPreview.tsx +243 -0
  351. package/src/components/triggers/index.ts +1 -0
  352. package/src/components/ui/alert-dialog.tsx +152 -0
  353. package/src/components/ui/badge.tsx +39 -0
  354. package/src/components/ui/button.tsx +58 -0
  355. package/src/components/ui/card.tsx +75 -0
  356. package/src/components/ui/codemirror-js-editor.tsx +432 -0
  357. package/src/components/ui/codemirror-json-editor.tsx +816 -0
  358. package/src/components/ui/codemirror-nunjucks-editor.tsx +451 -0
  359. package/src/components/ui/codemirror-vscode-theme.ts +243 -0
  360. package/src/components/ui/collapsible.tsx +12 -0
  361. package/src/components/ui/command.tsx +162 -0
  362. package/src/components/ui/dialog.tsx +140 -0
  363. package/src/components/ui/dropdown-menu.tsx +232 -0
  364. package/src/components/ui/empty-state.tsx +93 -0
  365. package/src/components/ui/input.tsx +26 -0
  366. package/src/components/ui/label.tsx +19 -0
  367. package/src/components/ui/popover.tsx +53 -0
  368. package/src/components/ui/resizable.tsx +61 -0
  369. package/src/components/ui/scroll-area.tsx +56 -0
  370. package/src/components/ui/select.tsx +179 -0
  371. package/src/components/ui/separator.tsx +26 -0
  372. package/src/components/ui/slider.tsx +58 -0
  373. package/src/components/ui/switch.tsx +22 -0
  374. package/src/components/ui/table.tsx +90 -0
  375. package/src/components/ui/textarea.tsx +23 -0
  376. package/src/components/ui/tooltip.tsx +54 -0
  377. package/src/components/ui/tree-view.tsx +574 -0
  378. package/src/contexts/AgentToolCallbacksContext.tsx +31 -0
  379. package/src/contexts/ApiContext.tsx +51 -0
  380. package/src/contexts/FlowDataContext.tsx +21 -0
  381. package/src/contexts/NodeRegistryContext.tsx +54 -0
  382. package/src/contexts/PluginRegistryContext.tsx +182 -0
  383. package/src/contexts/ThemeProvider.tsx +106 -0
  384. package/src/contexts/ValidationContext.tsx +122 -0
  385. package/src/demo/DemoInvect.tsx +42 -0
  386. package/src/demo/FlowViewer.tsx +294 -0
  387. package/src/demo/demo-api-client.ts +246 -0
  388. package/src/demo/index.ts +28 -0
  389. package/src/demo/sample-data.ts +1980 -0
  390. package/src/hooks/index.ts +1 -0
  391. package/src/hooks/use-document-title.ts +8 -0
  392. package/src/hooks/use-flow-data.ts +144 -0
  393. package/src/hooks/use-invect-portal-class.ts +27 -0
  394. package/src/hooks/useFlowEditorStore.ts +2 -0
  395. package/src/index.ts +70 -0
  396. package/src/lib/utils.ts +6 -0
  397. package/src/prettier.d.ts +13 -0
  398. package/src/routes/all-flow-runs.tsx +27 -0
  399. package/src/routes/credentials.tsx +362 -0
  400. package/src/routes/flow-route-layout.tsx +113 -0
  401. package/src/routes/flow-runs.tsx +22 -0
  402. package/src/routes/flow.tsx +22 -0
  403. package/src/routes/home.tsx +282 -0
  404. package/src/services/index.ts +6 -0
  405. package/src/stores/executionViewStore.ts +211 -0
  406. package/src/stores/flow-editor.store.ts +738 -0
  407. package/src/stores/flowEditorStore.ts +2 -0
  408. package/src/stores/index.ts +10 -0
  409. package/src/stores/uiStore.ts +189 -0
  410. package/src/types/agent-tools.types.ts +64 -0
  411. package/src/types/index.ts +5 -0
  412. package/src/types/node-definition.types.ts +104 -0
  413. package/src/types/plugin.types.ts +123 -0
  414. package/src/utils/credentialBranding.ts +116 -0
  415. package/src/utils/credentialFiltering.ts +68 -0
  416. package/src/utils/flowTransformations.ts +137 -0
  417. package/src/utils/layoutUtils.ts +127 -0
  418. package/src/utils/nodeReferenceUtils.ts +135 -0
  419. package/src/vendor.d.ts +7 -0
@@ -0,0 +1,360 @@
1
+ /**
2
+ * OAuth2 Provider Selector Component
3
+ *
4
+ * Shows available OAuth2 providers grouped by category with connect buttons.
5
+ */
6
+
7
+ import React, { useState, useMemo, useEffect } from 'react';
8
+ import { Button } from '../ui/button';
9
+ import { Input } from '../ui/input';
10
+ import { Label } from '../ui/label';
11
+ import { Badge } from '../ui/badge';
12
+ import { ScrollArea } from '../ui/scroll-area';
13
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/dialog';
14
+ import {
15
+ ExternalLink,
16
+ FileText,
17
+ HardDrive,
18
+ Mail,
19
+ Calendar,
20
+ Github,
21
+ MessageSquare,
22
+ Cloud,
23
+ Table,
24
+ CheckSquare,
25
+ Bug,
26
+ Search,
27
+ } from 'lucide-react';
28
+ import { cn } from '../../lib/utils';
29
+ import { useOAuth2Providers } from '../../api/credentials.api';
30
+ import { OAuth2ConnectButton } from './OAuth2ConnectButton';
31
+ import type { OAuth2ProviderDefinition, Credential } from '../../api/types';
32
+ import { InvectLoader } from '../shared/InvectLoader';
33
+
34
+ // Icon mapping for providers
35
+ const providerIcons: Record<string, React.ElementType> = {
36
+ FileText,
37
+ HardDrive,
38
+ Mail,
39
+ Calendar,
40
+ Github,
41
+ MessageSquare,
42
+ Cloud,
43
+ Table,
44
+ CheckSquare,
45
+ Bug,
46
+ Sheet: Table,
47
+ };
48
+
49
+ // Category labels and colors
50
+ const categoryConfig: Record<string, { label: string; color: string }> = {
51
+ google: { label: 'Google', color: 'bg-info/15 text-info border-info/30' },
52
+ microsoft: { label: 'Microsoft', color: 'bg-info/15 text-info border-info/30' },
53
+ github: { label: 'GitHub', color: 'bg-muted text-muted-foreground border-border' },
54
+ slack: { label: 'Slack', color: 'bg-primary/15 text-primary border-primary/30' },
55
+ other: { label: 'Other', color: 'bg-warning/15 text-warning border-warning/30' },
56
+ };
57
+
58
+ interface OAuth2ProviderSelectorProps {
59
+ open: boolean;
60
+ onOpenChange: (open: boolean) => void;
61
+ /** Called when a credential is successfully created */
62
+ onCredentialCreated?: (credential: Credential) => void;
63
+ /** Portal container for modals */
64
+ portalContainer?: HTMLElement | null;
65
+ /** Filter to only show specific providers by ID (e.g., ["google"]) */
66
+ filterProviders?: string[];
67
+ /** Override scopes for the OAuth flow (uses provider defaults if not set) */
68
+ scopes?: string[];
69
+ }
70
+
71
+ export function OAuth2ProviderSelector({
72
+ open,
73
+ onOpenChange,
74
+ onCredentialCreated,
75
+ portalContainer,
76
+ filterProviders,
77
+ scopes,
78
+ }: OAuth2ProviderSelectorProps) {
79
+ const { data: providers, isLoading } = useOAuth2Providers();
80
+ const [searchQuery, setSearchQuery] = useState('');
81
+ const [selectedProvider, setSelectedProvider] = useState<OAuth2ProviderDefinition | null>(null);
82
+ const [clientId, setClientId] = useState('');
83
+ const [clientSecret, setClientSecret] = useState('');
84
+ const [credentialName, setCredentialName] = useState('');
85
+
86
+ // Filter providers by the filterProviders prop first, then by search
87
+ const availableProviders = useMemo(() => {
88
+ if (!providers) {
89
+ return [];
90
+ }
91
+ if (!filterProviders || filterProviders.length === 0) {
92
+ return providers;
93
+ }
94
+ return providers.filter((p) => filterProviders.includes(p.id));
95
+ }, [providers, filterProviders]);
96
+
97
+ // Further filter by search query
98
+ const filteredProviders = availableProviders.filter(
99
+ (p) =>
100
+ p.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
101
+ p.description.toLowerCase().includes(searchQuery.toLowerCase()),
102
+ );
103
+
104
+ // If there's only one provider after filtering, auto-select it
105
+ useEffect(() => {
106
+ if (open && availableProviders.length === 1 && !selectedProvider) {
107
+ setSelectedProvider(availableProviders[0]);
108
+ setCredentialName(availableProviders[0].name);
109
+ }
110
+ }, [open, availableProviders, selectedProvider]);
111
+
112
+ // Group providers by category
113
+ const providersByCategory = filteredProviders?.reduce(
114
+ (acc, provider) => {
115
+ const category = provider.category;
116
+ if (!acc[category]) {
117
+ acc[category] = [];
118
+ }
119
+ acc[category].push(provider);
120
+ return acc;
121
+ },
122
+ {} as Record<string, OAuth2ProviderDefinition[]>,
123
+ );
124
+
125
+ // Reset state when modal closes
126
+ useEffect(() => {
127
+ if (!open) {
128
+ setSelectedProvider(null);
129
+ setClientId('');
130
+ setClientSecret('');
131
+ setCredentialName('');
132
+ setSearchQuery('');
133
+ }
134
+ }, [open]);
135
+
136
+ const handleProviderSelect = (provider: OAuth2ProviderDefinition) => {
137
+ setSelectedProvider(provider);
138
+ setCredentialName(provider.name);
139
+ };
140
+
141
+ const handleBack = () => {
142
+ setSelectedProvider(null);
143
+ setClientId('');
144
+ setClientSecret('');
145
+ setCredentialName('');
146
+ };
147
+
148
+ const handleSuccess = (credential: Credential) => {
149
+ onCredentialCreated?.(credential);
150
+ onOpenChange(false);
151
+ // Reset state
152
+ setSelectedProvider(null);
153
+ setClientId('');
154
+ setClientSecret('');
155
+ setCredentialName('');
156
+ };
157
+
158
+ // Get redirect URI for OAuth callback
159
+ const redirectUri =
160
+ typeof window !== 'undefined' ? `${window.location.origin}/oauth/callback` : '';
161
+
162
+ return (
163
+ <Dialog open={open} onOpenChange={onOpenChange}>
164
+ <DialogContent
165
+ container={portalContainer}
166
+ className="sm:max-w-lg max-h-[80vh] overflow-hidden flex flex-col"
167
+ >
168
+ <DialogHeader>
169
+ <DialogTitle>
170
+ {selectedProvider ? `Connect ${selectedProvider.name}` : 'Connect OAuth2 Provider'}
171
+ </DialogTitle>
172
+ <DialogDescription>
173
+ {selectedProvider
174
+ ? 'Enter your OAuth2 app credentials to connect'
175
+ : 'Select a service to connect with OAuth2'}
176
+ </DialogDescription>
177
+ </DialogHeader>
178
+
179
+ {isLoading ? (
180
+ <div className="flex items-center justify-center py-8">
181
+ <InvectLoader iconClassName="h-14" label="Loading providers..." />
182
+ </div>
183
+ ) : selectedProvider ? (
184
+ // Configuration form for selected provider
185
+ <div className="space-y-4">
186
+ <div className="flex items-center gap-3 p-3 rounded-lg bg-muted/50">
187
+ {providerIcons[selectedProvider.icon || 'FileText'] &&
188
+ React.createElement(providerIcons[selectedProvider.icon || 'FileText'], {
189
+ className: 'w-6 h-6',
190
+ })}
191
+ <div>
192
+ <p className="font-medium">{selectedProvider.name}</p>
193
+ <p className="text-xs text-muted-foreground">{selectedProvider.description}</p>
194
+ </div>
195
+ </div>
196
+
197
+ <div className="space-y-3">
198
+ <div className="space-y-1.5">
199
+ <Label htmlFor="credentialName" className="text-xs">
200
+ Credential Name
201
+ </Label>
202
+ <Input
203
+ id="credentialName"
204
+ value={credentialName}
205
+ onChange={(e) => setCredentialName(e.target.value)}
206
+ placeholder="My Google Docs"
207
+ className="h-8 text-xs"
208
+ />
209
+ </div>
210
+
211
+ <div className="space-y-1.5">
212
+ <Label htmlFor="clientId" className="text-xs">
213
+ Client ID *
214
+ </Label>
215
+ <Input
216
+ id="clientId"
217
+ value={clientId}
218
+ onChange={(e) => setClientId(e.target.value)}
219
+ placeholder="Enter OAuth2 Client ID"
220
+ className="h-8 text-xs"
221
+ autoComplete="one-time-code"
222
+ data-1p-ignore
223
+ data-lpignore="true"
224
+ />
225
+ </div>
226
+
227
+ <div className="space-y-1.5">
228
+ <Label htmlFor="clientSecret" className="text-xs">
229
+ Client Secret *
230
+ </Label>
231
+ <Input
232
+ id="clientSecret"
233
+ type="text"
234
+ style={{ WebkitTextSecurity: 'disc' }}
235
+ value={clientSecret}
236
+ onChange={(e) => setClientSecret(e.target.value)}
237
+ placeholder="Enter OAuth2 Client Secret"
238
+ className="h-8 text-xs"
239
+ autoComplete="one-time-code"
240
+ data-1p-ignore
241
+ data-lpignore="true"
242
+ />
243
+ </div>
244
+
245
+ <div className="p-2 text-xs rounded-lg bg-muted/50">
246
+ <p className="font-medium mb-1">Redirect URI</p>
247
+ <code className="block p-1.5 rounded bg-background text-xs font-mono break-all">
248
+ {redirectUri}
249
+ </code>
250
+ <p className="mt-1 text-xs text-muted-foreground">
251
+ Add this URL to your OAuth app's allowed redirect URIs
252
+ </p>
253
+ </div>
254
+
255
+ {selectedProvider.docsUrl && (
256
+ <a
257
+ href={selectedProvider.docsUrl}
258
+ target="_blank"
259
+ rel="noopener noreferrer"
260
+ className="inline-flex items-center gap-1.5 text-xs text-primary hover:underline"
261
+ >
262
+ <ExternalLink className="w-3 h-3" />
263
+ View setup documentation
264
+ </a>
265
+ )}
266
+ </div>
267
+
268
+ <div className="flex gap-2 pt-2">
269
+ <Button variant="outline" onClick={handleBack} className="flex-1 h-8 text-xs">
270
+ Back
271
+ </Button>
272
+ <OAuth2ConnectButton
273
+ provider={selectedProvider}
274
+ clientId={clientId}
275
+ clientSecret={clientSecret}
276
+ redirectUri={redirectUri}
277
+ scopes={scopes}
278
+ credentialName={credentialName}
279
+ onSuccess={handleSuccess}
280
+ disabled={!clientId || !clientSecret}
281
+ className="flex-1 h-8 text-xs"
282
+ variant="default"
283
+ />
284
+ </div>
285
+ </div>
286
+ ) : (
287
+ // Provider selection list
288
+ <div className="flex flex-col min-h-0 -mx-6">
289
+ {/* Search */}
290
+ <div className="px-6 pb-3">
291
+ <div className="relative">
292
+ <Search className="absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 pointer-events-none text-muted-foreground" />
293
+ <input
294
+ type="text"
295
+ placeholder="Search providers…"
296
+ value={searchQuery}
297
+ onChange={(e) => setSearchQuery(e.target.value)}
298
+ className="h-8 w-full rounded-lg border border-border bg-transparent pl-9 pr-3 text-xs outline-none placeholder:text-muted-foreground focus:border-primary/50"
299
+ />
300
+ </div>
301
+ </div>
302
+
303
+ {/* Provider list */}
304
+ <ScrollArea className="flex-1 px-6">
305
+ <div className="space-y-4 pb-4">
306
+ {providersByCategory &&
307
+ Object.entries(providersByCategory).map(([category, categoryProviders]) => {
308
+ const config = categoryConfig[category] || categoryConfig.other;
309
+ return (
310
+ <div key={category}>
311
+ <h3 className="mb-2 text-xs font-medium text-muted-foreground">
312
+ {config.label}
313
+ </h3>
314
+ <div className="space-y-2">
315
+ {categoryProviders.map((provider) => {
316
+ const Icon = providerIcons[provider.icon || 'FileText'] || FileText;
317
+ return (
318
+ <button
319
+ key={provider.id}
320
+ onClick={() => handleProviderSelect(provider)}
321
+ className="flex items-center w-full gap-3 p-3 text-left transition-colors border rounded-lg hover:bg-muted/50"
322
+ >
323
+ <div
324
+ className={cn(
325
+ 'flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border',
326
+ config.color,
327
+ )}
328
+ >
329
+ <Icon className="w-4 h-4" />
330
+ </div>
331
+ <div className="flex-1 min-w-0">
332
+ <p className="text-sm font-medium">{provider.name}</p>
333
+ <p className="text-xs truncate text-muted-foreground">
334
+ {provider.description}
335
+ </p>
336
+ </div>
337
+ <Badge variant="outline" className="text-xs shrink-0">
338
+ {provider.supportsRefresh ? 'Auto-refresh' : 'Manual'}
339
+ </Badge>
340
+ </button>
341
+ );
342
+ })}
343
+ </div>
344
+ </div>
345
+ );
346
+ })}
347
+
348
+ {(!filteredProviders || filteredProviders.length === 0) && (
349
+ <div className="py-8 text-center text-muted-foreground">
350
+ <p className="text-sm">No providers found</p>
351
+ </div>
352
+ )}
353
+ </div>
354
+ </ScrollArea>
355
+ </div>
356
+ )}
357
+ </DialogContent>
358
+ </Dialog>
359
+ );
360
+ }
@@ -0,0 +1,99 @@
1
+ import type { Credential, CredentialAuthType, CredentialType } from '../../api/types';
2
+
3
+ // ── Auth type config ───────────────────────────────────────────────────
4
+
5
+ export const AUTH_TYPE_CONFIG: Record<string, { label: string; color: string }> = {
6
+ bearer: {
7
+ label: 'Bearer',
8
+ color: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300',
9
+ },
10
+ apiKey: {
11
+ label: 'API Key',
12
+ color: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300',
13
+ },
14
+ basic: {
15
+ label: 'Basic',
16
+ color: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300',
17
+ },
18
+ oauth2: {
19
+ label: 'OAuth 2.0',
20
+ color: 'bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-300',
21
+ },
22
+ custom: { label: 'Custom', color: 'bg-muted text-muted-foreground' },
23
+ awsSigV4: {
24
+ label: 'AWS Sig V4',
25
+ color: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300',
26
+ },
27
+ jwt: { label: 'JWT', color: 'bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-300' },
28
+ connectionString: {
29
+ label: 'Connection',
30
+ color: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-900/30 dark:text-cyan-300',
31
+ },
32
+ };
33
+
34
+ // ── Dates ──────────────────────────────────────────────────────────────
35
+
36
+ export const formatDate = (dateString?: string) => {
37
+ if (!dateString) {
38
+ return 'Never';
39
+ }
40
+ const date = new Date(dateString);
41
+ const now = new Date();
42
+ const diff = now.getTime() - date.getTime();
43
+ const seconds = Math.floor(diff / 1000);
44
+ const minutes = Math.floor(seconds / 60);
45
+ const hours = Math.floor(minutes / 60);
46
+ const days = Math.floor(hours / 24);
47
+
48
+ if (seconds < 60) {
49
+ return 'Just now';
50
+ }
51
+ if (minutes < 60) {
52
+ return `${minutes}m ago`;
53
+ }
54
+ if (hours < 24) {
55
+ return `${hours}h ago`;
56
+ }
57
+ if (days < 30) {
58
+ return `${days}d ago`;
59
+ }
60
+ return date.toLocaleDateString();
61
+ };
62
+
63
+ export const formatFullDate = (dateString?: string) => {
64
+ if (!dateString) {
65
+ return 'Never';
66
+ }
67
+ return new Date(dateString).toLocaleString();
68
+ };
69
+
70
+ export function isTokenExpired(credential: Credential): boolean {
71
+ const expiresAt = credential.expiresAt || credential.config?.expiresAt;
72
+ if (!expiresAt) {
73
+ return false;
74
+ }
75
+ return new Date(expiresAt) < new Date();
76
+ }
77
+
78
+ // ── Edit form auth type helpers ────────────────────────────────────────
79
+
80
+ const ALL_AUTH_TYPES: { value: CredentialAuthType; label: string }[] = [
81
+ { value: 'bearer', label: 'Bearer Token' },
82
+ { value: 'apiKey', label: 'API Key' },
83
+ { value: 'basic', label: 'Basic Auth' },
84
+ { value: 'oauth2', label: 'OAuth2' },
85
+ { value: 'custom', label: 'Custom Headers' },
86
+ { value: 'awsSigV4', label: 'AWS Signature V4' },
87
+ { value: 'jwt', label: 'JWT' },
88
+ { value: 'connectionString', label: 'Connection String' },
89
+ ];
90
+
91
+ export function getAuthTypesForType(type: CredentialType) {
92
+ if (type === 'database') {
93
+ return ALL_AUTH_TYPES.filter((t) => ['basic', 'connectionString', 'oauth2'].includes(t.value));
94
+ }
95
+ if (type === 'llm') {
96
+ return ALL_AUTH_TYPES.filter((t) => ['apiKey', 'bearer'].includes(t.value));
97
+ }
98
+ return ALL_AUTH_TYPES.filter((t) => !['connectionString'].includes(t.value));
99
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Credentials Components
3
+ *
4
+ * Export all credential-related components.
5
+ */
6
+
7
+ export { CreateCredentialModal } from './CreateCredentialModal';
8
+ export { EditCredentialModal } from './EditCredentialModal';
9
+ export { OAuth2ConnectButton, OAuth2CallbackHandler } from './OAuth2ConnectButton';
10
+ export { OAuth2ProviderSelector } from './OAuth2ProviderSelector';
@@ -0,0 +1,67 @@
1
+ import { Link } from 'react-router';
2
+ import { AlertTriangle, XCircle, ArrowRight } from 'lucide-react';
3
+ import { Button } from '~/components/ui/button';
4
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';
5
+ import { useListFlowRuns } from '~/api/executions.api';
6
+ import { formatRelativeTime } from './status-helpers';
7
+
8
+ export function FailedRunsAlert({ basePath }: { basePath: string }) {
9
+ const { data: failedResponse, isLoading } = useListFlowRuns(
10
+ undefined,
11
+ 'FAILED',
12
+ 1,
13
+ 5,
14
+ 'startedAt',
15
+ 'desc',
16
+ );
17
+
18
+ const failedRuns = failedResponse?.data ?? [];
19
+
20
+ if (isLoading || failedRuns.length === 0) {
21
+ return null;
22
+ }
23
+
24
+ return (
25
+ <Card className="border-red-200 dark:border-red-900 gap-0 py-0">
26
+ <CardHeader className="pb-2 pt-4">
27
+ <div className="flex items-center gap-2">
28
+ <AlertTriangle className="h-4 w-4 text-red-500" />
29
+ <CardTitle className="text-sm">Attention Required</CardTitle>
30
+ </div>
31
+ <CardDescription className="text-xs">
32
+ Recent failed runs that may need investigation
33
+ </CardDescription>
34
+ </CardHeader>
35
+ <CardContent className="pb-4">
36
+ <div className="space-y-2">
37
+ {failedRuns.map((run) => (
38
+ <Link
39
+ key={run.id}
40
+ to={`${basePath}/flow/${run.flowId}`}
41
+ className="flex items-center justify-between rounded-md border border-red-100 dark:border-red-900/50 bg-red-50/50 dark:bg-red-950/20 p-2.5 text-sm hover:bg-red-100/50 dark:hover:bg-red-950/40 transition-colors"
42
+ >
43
+ <div className="flex items-center gap-2 min-w-0">
44
+ <XCircle className="h-3.5 w-3.5 text-red-500 shrink-0" />
45
+ <span className="truncate font-medium text-xs">{run.flowId.slice(0, 24)}</span>
46
+ {run.error && (
47
+ <span className="text-xs text-red-600/70 dark:text-red-400/70 truncate max-w-[200px]">
48
+ {run.error}
49
+ </span>
50
+ )}
51
+ </div>
52
+ <span className="text-xs text-muted-foreground shrink-0 ml-2">
53
+ {formatRelativeTime(run.startedAt)}
54
+ </span>
55
+ </Link>
56
+ ))}
57
+ </div>
58
+ <Button variant="ghost" size="sm" asChild className="mt-2 w-full text-xs">
59
+ <Link to={`${basePath}/flow-runs`}>
60
+ View all flow runs
61
+ <ArrowRight className="ml-1 h-3 w-3" />
62
+ </Link>
63
+ </Button>
64
+ </CardContent>
65
+ </Card>
66
+ );
67
+ }
@@ -0,0 +1,64 @@
1
+ import { Link, useNavigate } from 'react-router';
2
+ import { Edit, History } from 'lucide-react';
3
+ import { Button } from '~/components/ui/button';
4
+ import { useLatestFlowRun } from '~/api/executions.api';
5
+ import { StatusBadge, formatRelativeTime } from './status-helpers';
6
+ import type { Flow } from '@invect/core/types';
7
+
8
+ interface FlowCardProps {
9
+ flow: Flow;
10
+ basePath: string;
11
+ }
12
+
13
+ export function FlowCard({ flow, basePath }: FlowCardProps) {
14
+ const { data: latestRun } = useLatestFlowRun(flow.id);
15
+ const navigate = useNavigate();
16
+
17
+ return (
18
+ <div
19
+ className="flex items-center justify-between px-4 py-3 transition-all border rounded-lg cursor-pointer group bg-card hover:shadow-sm hover:border-primary/20"
20
+ onClick={() => navigate(`${basePath}/flow/${flow.id}`)}
21
+ >
22
+ <div className="flex-1 min-w-0">
23
+ <div className="flex items-center gap-2.5">
24
+ <h3 className="text-sm font-medium truncate">{flow.name}</h3>
25
+ {latestRun && <StatusBadge status={latestRun.status} />}
26
+ </div>
27
+ <div className="mt-1.5 flex items-center gap-3 text-xs text-muted-foreground">
28
+ {flow.description && <span className="truncate max-w-75">{flow.description}</span>}
29
+ {latestRun ? (
30
+ <span className="shrink-0">Last run {formatRelativeTime(latestRun.startedAt)}</span>
31
+ ) : (
32
+ <span className="italic">Never run</span>
33
+ )}
34
+ </div>
35
+ </div>
36
+ <div className="flex items-center gap-2 ml-4 transition-opacity opacity-0 group-hover:opacity-100">
37
+ <Button
38
+ size="sm"
39
+ variant="outline"
40
+ className="text-xs h-7"
41
+ onClick={(e) => {
42
+ e.stopPropagation();
43
+ navigate(`${basePath}/flow/${flow.id}`);
44
+ }}
45
+ >
46
+ <Edit className="w-3 h-3 mr-1" />
47
+ Edit
48
+ </Button>
49
+ <Button
50
+ size="sm"
51
+ variant="outline"
52
+ className="text-xs h-7"
53
+ asChild
54
+ onClick={(e) => e.stopPropagation()}
55
+ >
56
+ <Link to={`${basePath}/flow/${flow.id}/runs`}>
57
+ <History className="w-3 h-3 mr-1" />
58
+ Runs
59
+ </Link>
60
+ </Button>
61
+ </div>
62
+ </div>
63
+ );
64
+ }