@dxos/plugin-automation 0.8.4-main.72ec0f3 → 0.8.4-main.74a063c4e0

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 (282) hide show
  1. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/browser/chunk-POEIL4RN.mjs +44 -0
  3. package/dist/lib/browser/chunk-POEIL4RN.mjs.map +7 -0
  4. package/dist/lib/browser/chunk-WQLEMRPU.mjs +54 -0
  5. package/dist/lib/browser/chunk-WQLEMRPU.mjs.map +7 -0
  6. package/dist/lib/browser/cli/index.mjs +1122 -0
  7. package/dist/lib/browser/cli/index.mjs.map +7 -0
  8. package/dist/lib/browser/create-trigger-from-template-JPF5BFMX.mjs +77 -0
  9. package/dist/lib/browser/create-trigger-from-template-JPF5BFMX.mjs.map +7 -0
  10. package/dist/lib/browser/hooks/index.mjs +79 -7
  11. package/dist/lib/browser/hooks/index.mjs.map +4 -4
  12. package/dist/lib/browser/index.mjs +72 -112
  13. package/dist/lib/browser/index.mjs.map +4 -4
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/operations/index.mjs +14 -0
  16. package/dist/lib/browser/operations/index.mjs.map +7 -0
  17. package/dist/lib/browser/types/index.mjs +10 -4
  18. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  19. package/dist/lib/node-esm/{chunk-ECJKIUBO.mjs → chunk-JWZAVQLF.mjs} +24 -7
  20. package/dist/lib/node-esm/chunk-JWZAVQLF.mjs.map +7 -0
  21. package/dist/lib/node-esm/chunk-SP3P4OUI.mjs +45 -0
  22. package/dist/lib/node-esm/chunk-SP3P4OUI.mjs.map +7 -0
  23. package/dist/lib/node-esm/cli/index.mjs +1123 -0
  24. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  25. package/dist/lib/node-esm/create-trigger-from-template-FT75A4SF.mjs +78 -0
  26. package/dist/lib/node-esm/create-trigger-from-template-FT75A4SF.mjs.map +7 -0
  27. package/dist/lib/node-esm/hooks/index.mjs +79 -7
  28. package/dist/lib/node-esm/hooks/index.mjs.map +4 -4
  29. package/dist/lib/node-esm/index.mjs +72 -112
  30. package/dist/lib/node-esm/index.mjs.map +4 -4
  31. package/dist/lib/node-esm/meta.json +1 -1
  32. package/dist/lib/node-esm/operations/index.mjs +15 -0
  33. package/dist/lib/node-esm/operations/index.mjs.map +7 -0
  34. package/dist/lib/node-esm/types/index.mjs +10 -4
  35. package/dist/types/src/AutomationPlugin.d.ts +2 -1
  36. package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
  37. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  38. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  39. package/dist/types/src/capabilities/compute-runtime.d.ts +4 -3
  40. package/dist/types/src/capabilities/compute-runtime.d.ts.map +1 -1
  41. package/dist/types/src/capabilities/index.d.ts +6 -5
  42. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  43. package/dist/types/src/capabilities/node.d.ts +3 -0
  44. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  45. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  46. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  47. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  48. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  49. package/dist/types/src/cli/commands/index.d.ts +2 -0
  50. package/dist/types/src/cli/commands/index.d.ts.map +1 -0
  51. package/dist/types/src/cli/commands/trigger/create/index.d.ts +25 -0
  52. package/dist/types/src/cli/commands/trigger/create/index.d.ts.map +1 -0
  53. package/dist/types/src/cli/commands/trigger/create/queue.d.ts +13 -0
  54. package/dist/types/src/cli/commands/trigger/create/queue.d.ts.map +1 -0
  55. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts +15 -0
  56. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts.map +1 -0
  57. package/dist/types/src/cli/commands/trigger/create/timer.d.ts +13 -0
  58. package/dist/types/src/cli/commands/trigger/create/timer.d.ts.map +1 -0
  59. package/dist/types/src/cli/commands/trigger/index.d.ts +57 -0
  60. package/dist/types/src/cli/commands/trigger/index.d.ts.map +1 -0
  61. package/dist/types/src/cli/commands/trigger/list.d.ts +7 -0
  62. package/dist/types/src/cli/commands/trigger/list.d.ts.map +1 -0
  63. package/dist/types/src/cli/commands/trigger/options.d.ts +11 -0
  64. package/dist/types/src/cli/commands/trigger/options.d.ts.map +1 -0
  65. package/dist/types/src/cli/commands/trigger/remove.d.ts +8 -0
  66. package/dist/types/src/cli/commands/trigger/remove.d.ts.map +1 -0
  67. package/dist/types/src/cli/commands/trigger/update/index.d.ts +28 -0
  68. package/dist/types/src/cli/commands/trigger/update/index.d.ts.map +1 -0
  69. package/dist/types/src/cli/commands/trigger/update/queue.d.ts +12 -0
  70. package/dist/types/src/cli/commands/trigger/update/queue.d.ts.map +1 -0
  71. package/dist/types/src/cli/commands/trigger/update/subscription.d.ts +13 -0
  72. package/dist/types/src/cli/commands/trigger/update/subscription.d.ts.map +1 -0
  73. package/dist/types/src/cli/commands/trigger/update/timer.d.ts +11 -0
  74. package/dist/types/src/cli/commands/trigger/update/timer.d.ts.map +1 -0
  75. package/dist/types/src/cli/commands/trigger/util.d.ts +46 -0
  76. package/dist/types/src/cli/commands/trigger/util.d.ts.map +1 -0
  77. package/dist/types/src/cli/index.d.ts +2 -0
  78. package/dist/types/src/cli/index.d.ts.map +1 -0
  79. package/dist/types/src/cli/plugin.d.ts +3 -0
  80. package/dist/types/src/cli/plugin.d.ts.map +1 -0
  81. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +4 -5
  82. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  83. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +28 -29
  84. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
  86. package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -1
  87. package/dist/types/src/components/FunctionsRegistry/index.d.ts +3 -1
  88. package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -1
  89. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +12 -9
  90. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
  91. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts +6 -3
  92. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -1
  93. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +7 -6
  94. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  95. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +98 -31
  96. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/index.d.ts +3 -4
  98. package/dist/types/src/components/index.d.ts.map +1 -1
  99. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +4 -0
  100. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
  101. package/dist/types/src/containers/AutomationSettings/index.d.ts +2 -0
  102. package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
  103. package/dist/types/src/{components → containers/FunctionsContainer}/FunctionsContainer.d.ts +0 -1
  104. package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
  105. package/dist/types/src/containers/FunctionsContainer/index.d.ts +2 -0
  106. package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
  107. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts +6 -0
  108. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
  109. package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
  110. package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
  111. package/dist/types/src/containers/index.d.ts +5 -0
  112. package/dist/types/src/containers/index.d.ts.map +1 -0
  113. package/dist/types/src/hooks/index.d.ts +2 -0
  114. package/dist/types/src/hooks/index.d.ts.map +1 -1
  115. package/dist/types/src/hooks/useComputeRuntime.d.ts +7 -0
  116. package/dist/types/src/hooks/useComputeRuntime.d.ts.map +1 -0
  117. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts +4 -7
  118. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts.map +1 -1
  119. package/dist/types/src/hooks/useComputeRuntimeService.d.ts +5 -0
  120. package/dist/types/src/hooks/useComputeRuntimeService.d.ts.map +1 -0
  121. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +4 -3
  122. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
  123. package/dist/types/src/index.d.ts +2 -6
  124. package/dist/types/src/index.d.ts.map +1 -1
  125. package/dist/types/src/meta.d.ts +2 -2
  126. package/dist/types/src/meta.d.ts.map +1 -1
  127. package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
  128. package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
  129. package/dist/types/src/operations/definitions.d.ts +19 -0
  130. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  131. package/dist/types/src/operations/index.d.ts +4 -0
  132. package/dist/types/src/operations/index.d.ts.map +1 -0
  133. package/dist/types/src/testing/test-functions.d.ts +204 -3
  134. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  135. package/dist/types/src/translations.d.ts +29 -30
  136. package/dist/types/src/translations.d.ts.map +1 -1
  137. package/dist/types/src/types/capabilities.d.ts +25 -0
  138. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  139. package/dist/types/src/types/events.d.ts +5 -0
  140. package/dist/types/src/types/events.d.ts.map +1 -0
  141. package/dist/types/src/types/index.d.ts +2 -0
  142. package/dist/types/src/types/index.d.ts.map +1 -1
  143. package/dist/types/src/types/schema.d.ts +11 -3
  144. package/dist/types/src/types/schema.d.ts.map +1 -1
  145. package/dist/types/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +89 -50
  147. package/src/AutomationPlugin.tsx +18 -35
  148. package/src/capabilities/app-graph-builder.ts +54 -79
  149. package/src/capabilities/compute-runtime.ts +172 -53
  150. package/src/capabilities/index.ts +9 -7
  151. package/src/capabilities/node.ts +7 -0
  152. package/src/capabilities/operation-handler.ts +16 -0
  153. package/src/capabilities/react-surface.tsx +49 -46
  154. package/src/cli/commands/index.ts +5 -0
  155. package/src/cli/commands/trigger/create/index.ts +14 -0
  156. package/src/cli/commands/trigger/create/queue.ts +90 -0
  157. package/src/cli/commands/trigger/create/subscription.ts +129 -0
  158. package/src/cli/commands/trigger/create/timer.ts +94 -0
  159. package/src/cli/commands/trigger/index.ts +16 -0
  160. package/src/cli/commands/trigger/list.ts +68 -0
  161. package/src/cli/commands/trigger/options.ts +59 -0
  162. package/src/cli/commands/trigger/remove.ts +45 -0
  163. package/src/cli/commands/trigger/update/index.ts +14 -0
  164. package/src/cli/commands/trigger/update/queue.ts +195 -0
  165. package/src/cli/commands/trigger/update/subscription.ts +279 -0
  166. package/src/cli/commands/trigger/update/timer.ts +194 -0
  167. package/src/cli/commands/trigger/util.ts +409 -0
  168. package/src/cli/index.ts +5 -0
  169. package/src/cli/plugin.ts +23 -0
  170. package/src/components/AutomationPanel/AutomationPanel.stories.tsx +10 -8
  171. package/src/components/AutomationPanel/AutomationPanel.tsx +174 -75
  172. package/src/components/FunctionsPanel/FunctionsPanel.tsx +42 -41
  173. package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +28 -49
  174. package/src/components/FunctionsRegistry/index.ts +4 -1
  175. package/src/components/TriggerEditor/FunctionInputEditor.tsx +34 -33
  176. package/src/components/TriggerEditor/SpecSelector.tsx +20 -9
  177. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +80 -34
  178. package/src/components/TriggerEditor/TriggerEditor.tsx +90 -48
  179. package/src/components/index.ts +1 -2
  180. package/src/containers/AutomationSettings/AutomationSettings.tsx +28 -0
  181. package/src/containers/AutomationSettings/index.ts +5 -0
  182. package/src/containers/FunctionsContainer/FunctionsContainer.tsx +34 -0
  183. package/src/containers/FunctionsContainer/index.ts +5 -0
  184. package/src/containers/TriggerSettings/TriggerSettings.tsx +26 -0
  185. package/src/containers/TriggerSettings/index.ts +6 -0
  186. package/src/containers/index.ts +9 -0
  187. package/src/hooks/index.ts +3 -0
  188. package/src/hooks/useComputeRuntime.ts +16 -0
  189. package/src/hooks/useComputeRuntimeCallback.ts +8 -44
  190. package/src/hooks/useComputeRuntimeService.ts +24 -0
  191. package/src/hooks/useTriggerRuntimeControls.ts +28 -14
  192. package/src/index.ts +2 -7
  193. package/src/meta.ts +3 -3
  194. package/src/operations/create-trigger-from-template.ts +75 -0
  195. package/src/operations/definitions.ts +28 -0
  196. package/src/operations/index.ts +9 -0
  197. package/src/testing/test-functions.ts +9 -6
  198. package/src/translations.ts +35 -34
  199. package/src/types/capabilities.ts +56 -0
  200. package/src/types/events.ts +11 -0
  201. package/src/types/index.ts +2 -0
  202. package/src/types/schema.ts +5 -5
  203. package/dist/lib/browser/AutomationPanel-7OECLR5N.mjs +0 -11
  204. package/dist/lib/browser/AutomationSettings-KCZISXI6.mjs +0 -68
  205. package/dist/lib/browser/AutomationSettings-KCZISXI6.mjs.map +0 -7
  206. package/dist/lib/browser/FunctionsContainer-MIWEISRR.mjs +0 -151
  207. package/dist/lib/browser/FunctionsContainer-MIWEISRR.mjs.map +0 -7
  208. package/dist/lib/browser/FunctionsPanel-CRW6SJUN.mjs +0 -10
  209. package/dist/lib/browser/app-graph-builder-W7LLC6XW.mjs +0 -81
  210. package/dist/lib/browser/app-graph-builder-W7LLC6XW.mjs.map +0 -7
  211. package/dist/lib/browser/chunk-EPEXQP45.mjs +0 -14
  212. package/dist/lib/browser/chunk-EPEXQP45.mjs.map +0 -7
  213. package/dist/lib/browser/chunk-JW7XSPYW.mjs +0 -267
  214. package/dist/lib/browser/chunk-JW7XSPYW.mjs.map +0 -7
  215. package/dist/lib/browser/chunk-LZQFZO3B.mjs +0 -17
  216. package/dist/lib/browser/chunk-LZQFZO3B.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-NAPXRXTY.mjs +0 -100
  218. package/dist/lib/browser/chunk-NAPXRXTY.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-QKFBHAGN.mjs +0 -184
  220. package/dist/lib/browser/chunk-QKFBHAGN.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-TWWFNOIR.mjs +0 -109
  222. package/dist/lib/browser/chunk-TWWFNOIR.mjs.map +0 -7
  223. package/dist/lib/browser/chunk-XAKZ4ANY.mjs +0 -15
  224. package/dist/lib/browser/chunk-XAKZ4ANY.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-YBPJCY3F.mjs +0 -38
  226. package/dist/lib/browser/chunk-YBPJCY3F.mjs.map +0 -7
  227. package/dist/lib/browser/compute-runtime-EIQTHJFZ.mjs +0 -113
  228. package/dist/lib/browser/compute-runtime-EIQTHJFZ.mjs.map +0 -7
  229. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs +0 -77
  230. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs.map +0 -7
  231. package/dist/lib/browser/react-surface-YQW7WCFW.mjs +0 -64
  232. package/dist/lib/browser/react-surface-YQW7WCFW.mjs.map +0 -7
  233. package/dist/lib/node-esm/AutomationPanel-HCVFNHGQ.mjs +0 -12
  234. package/dist/lib/node-esm/AutomationPanel-HCVFNHGQ.mjs.map +0 -7
  235. package/dist/lib/node-esm/AutomationSettings-UUUPVNUJ.mjs +0 -69
  236. package/dist/lib/node-esm/AutomationSettings-UUUPVNUJ.mjs.map +0 -7
  237. package/dist/lib/node-esm/FunctionsContainer-6OB3JN5O.mjs +0 -152
  238. package/dist/lib/node-esm/FunctionsContainer-6OB3JN5O.mjs.map +0 -7
  239. package/dist/lib/node-esm/FunctionsPanel-RVVCS6VH.mjs +0 -11
  240. package/dist/lib/node-esm/FunctionsPanel-RVVCS6VH.mjs.map +0 -7
  241. package/dist/lib/node-esm/app-graph-builder-SLQOO7GH.mjs +0 -82
  242. package/dist/lib/node-esm/app-graph-builder-SLQOO7GH.mjs.map +0 -7
  243. package/dist/lib/node-esm/chunk-6YRKST6M.mjs +0 -185
  244. package/dist/lib/node-esm/chunk-6YRKST6M.mjs.map +0 -7
  245. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs +0 -19
  246. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs.map +0 -7
  247. package/dist/lib/node-esm/chunk-CPP35BE6.mjs +0 -16
  248. package/dist/lib/node-esm/chunk-CPP35BE6.mjs.map +0 -7
  249. package/dist/lib/node-esm/chunk-ECJKIUBO.mjs.map +0 -7
  250. package/dist/lib/node-esm/chunk-KB7NFEYY.mjs +0 -16
  251. package/dist/lib/node-esm/chunk-KB7NFEYY.mjs.map +0 -7
  252. package/dist/lib/node-esm/chunk-PICJ2REN.mjs +0 -101
  253. package/dist/lib/node-esm/chunk-PICJ2REN.mjs.map +0 -7
  254. package/dist/lib/node-esm/chunk-RVK52XGK.mjs +0 -110
  255. package/dist/lib/node-esm/chunk-RVK52XGK.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-W76WUTZY.mjs +0 -268
  257. package/dist/lib/node-esm/chunk-W76WUTZY.mjs.map +0 -7
  258. package/dist/lib/node-esm/compute-runtime-URROOC34.mjs +0 -114
  259. package/dist/lib/node-esm/compute-runtime-URROOC34.mjs.map +0 -7
  260. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs +0 -78
  261. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs.map +0 -7
  262. package/dist/lib/node-esm/react-surface-NNHYNBO6.mjs +0 -65
  263. package/dist/lib/node-esm/react-surface-NNHYNBO6.mjs.map +0 -7
  264. package/dist/types/src/capabilities/capabilities.d.ts +0 -20
  265. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  266. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  267. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  268. package/dist/types/src/components/AutomationSettings.d.ts +0 -5
  269. package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
  270. package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
  271. package/dist/types/src/components/TriggerSettings.d.ts +0 -6
  272. package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
  273. package/dist/types/src/events.d.ts +0 -4
  274. package/dist/types/src/events.d.ts.map +0 -1
  275. package/src/capabilities/capabilities.ts +0 -41
  276. package/src/capabilities/intent-resolver.ts +0 -72
  277. package/src/components/AutomationSettings.tsx +0 -30
  278. package/src/components/FunctionsContainer.tsx +0 -36
  279. package/src/components/TriggerSettings.tsx +0 -25
  280. package/src/events.ts +0 -11
  281. /package/dist/lib/browser/{AutomationPanel-7OECLR5N.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  282. /package/dist/lib/{browser/FunctionsPanel-CRW6SJUN.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
@@ -2,29 +2,26 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import type * as SchemaAST from 'effect/SchemaAST';
5
6
  import React, { useCallback, useMemo } from 'react';
6
7
 
7
- import { Ref, Type } from '@dxos/echo';
8
+ import { type Database, JsonSchema, Obj, Ref } from '@dxos/echo';
8
9
  import { type JsonPath } from '@dxos/echo/internal';
9
- import { type Function } from '@dxos/functions';
10
- import { useOnTransition } from '@dxos/react-ui';
11
- import { Form, type FormInputStateProps, type QueryRefOptions, useFormValues } from '@dxos/react-ui-form';
10
+ import { type Operation } from '@dxos/operation';
11
+ import { useOnTransition, useTranslation } from '@dxos/react-ui';
12
+ import { Form, type FormFieldStateProps, type FormRootProps, useFormValues } from '@dxos/react-ui-form';
13
+
14
+ import { meta } from '#meta';
12
15
 
13
16
  export type FunctionInputEditorProps = {
14
- functions: Function.Function[];
15
- onQueryRefOptions: QueryRefOptions;
16
- } & FormInputStateProps;
17
+ type: SchemaAST.AST;
18
+ functions: Operation.PersistentOperation[];
19
+ db?: Database.Database;
20
+ } & FormFieldStateProps;
17
21
 
18
- /**
19
- * Editor component for function input parameters.
20
- */
21
- export const FunctionInputEditor = ({
22
- functions,
23
- getValue,
24
- onValueChange,
25
- onQueryRefOptions,
26
- }: FunctionInputEditorProps) => {
27
- const selectedFunctionValue = useFormValues(['function' as JsonPath]);
22
+ export const FunctionInputEditor = ({ type, functions, db, getValue, onValueChange }: FunctionInputEditorProps) => {
23
+ const { t } = useTranslation(meta.id);
24
+ const selectedFunctionValue = useFormValues(FunctionInputEditor.displayName, ['function' as JsonPath]);
28
25
  const selectedFunctionId = useMemo(() => {
29
26
  if (Ref.isRef(selectedFunctionValue)) {
30
27
  return selectedFunctionValue.dxn.toString().split('dxn:echo:@:').at(1);
@@ -47,20 +44,22 @@ export const FunctionInputEditor = ({
47
44
  return prevValue.dxn.toString() !== selectedFunctionValue.dxn.toString();
48
45
  },
49
46
  (currValue) => currValue !== undefined,
50
- () => onValueChange('object', {}),
47
+ () => onValueChange(type, {}),
51
48
  );
52
49
 
53
50
  const inputSchema = useMemo(() => selectedFunction?.inputSchema, [selectedFunction]);
54
- const effectSchema = useMemo(() => (inputSchema ? Type.toEffectSchema(inputSchema) : undefined), [inputSchema]);
51
+ const effectSchema = useMemo(() => (inputSchema ? JsonSchema.toEffectSchema(inputSchema) : undefined), [inputSchema]);
55
52
  const propertyCount = inputSchema?.properties ? Object.keys(inputSchema.properties).length : 0;
53
+ const defaultValues = useMemo(() => {
54
+ const raw = getValue() ?? {};
55
+ return Obj.isObject(raw) ? { ...Obj.getSnapshot(raw) } : { ...raw };
56
+ }, [getValue]);
56
57
 
57
- const values = useMemo(() => getValue() ?? {}, [getValue]);
58
-
59
- const handleValuesChanged = useCallback(
60
- (values: any) => {
61
- onValueChange('object', values);
58
+ const handleValuesChanged = useCallback<NonNullable<FormRootProps['onValuesChanged']>>(
59
+ (values) => {
60
+ onValueChange(type, values);
62
61
  },
63
- [onValueChange],
62
+ [type, onValueChange],
64
63
  );
65
64
 
66
65
  if (selectedFunction === undefined || effectSchema === undefined || propertyCount === 0) {
@@ -69,16 +68,18 @@ export const FunctionInputEditor = ({
69
68
 
70
69
  return (
71
70
  <>
72
- <h3 className='text-md'>Function parameters</h3>
73
- {/* TODO(ZaymonFC): Try using <FormFields /> internal component for this nesting.
74
- This would allow errors to flow up to the root context. */}
75
- <Form
71
+ <Form.Label label={t('function-parameters.label')} asChild />
72
+ <Form.Root
73
+ key={selectedFunction.id}
76
74
  schema={effectSchema}
77
- values={values}
75
+ defaultValues={defaultValues}
76
+ db={db}
78
77
  onValuesChanged={handleValuesChanged}
79
- onQueryRefOptions={onQueryRefOptions}
80
- outerSpacing={false}
81
- />
78
+ >
79
+ <Form.FieldSet />
80
+ </Form.Root>
82
81
  </>
83
82
  );
84
83
  };
84
+
85
+ FunctionInputEditor.displayName = 'AutomationTrigger.FunctionInputEditor';
@@ -7,15 +7,15 @@ import React, { useCallback, useMemo } from 'react';
7
7
  import { Filter, Query } from '@dxos/echo';
8
8
  import { Trigger } from '@dxos/functions';
9
9
  import { useTranslation } from '@dxos/react-ui';
10
- import { type InputProps, SelectInput, useInputProps } from '@dxos/react-ui-form';
10
+ import { type FormFieldComponentProps, SelectField, useFormFieldState } from '@dxos/react-ui-form';
11
11
 
12
- import { meta } from '../../meta';
12
+ import { meta } from '#meta';
13
13
 
14
- export type SpecSelectorProps = InputProps;
14
+ export type SpecSelectorProps = FormFieldComponentProps;
15
15
 
16
16
  export const SpecSelector = (props: SpecSelectorProps) => {
17
17
  const { t } = useTranslation(meta.id);
18
- const specProps = useInputProps(['spec' satisfies keyof Trigger.Trigger]);
18
+ const specProps = useFormFieldState(SpecSelector.displayName, ['spec' satisfies keyof Trigger.Trigger]);
19
19
 
20
20
  const handleTypeChange = useCallback(
21
21
  (_type: any, value: string): Trigger.Spec | undefined => {
@@ -31,7 +31,7 @@ export const SpecSelector = (props: SpecSelectorProps) => {
31
31
  },
32
32
  };
33
33
  case 'queue':
34
- return { kind: 'queue', queue: 'dxn:' };
34
+ return { kind: 'queue', queue: 'dxn:queue:default' };
35
35
  case 'email':
36
36
  return { kind: 'email' };
37
37
  case 'webhook':
@@ -47,19 +47,30 @@ export const SpecSelector = (props: SpecSelectorProps) => {
47
47
  }
48
48
 
49
49
  // Update the entire spec object, not just the `spec.kind`.
50
- specProps.onValueChange('object', defaultSpec);
50
+ specProps.onValueChange(props.type, defaultSpec);
51
51
  },
52
- [specProps],
52
+ [props.type, specProps],
53
53
  );
54
54
 
55
+ const kindLabels: Record<string, string> = {
56
+ timer: t('trigger-type.timer.label'),
57
+ webhook: t('trigger-type.webhook.label'),
58
+ websocket: t('trigger-type.websocket.label'),
59
+ subscription: t('trigger-type.subscription.label'),
60
+ email: t('trigger-type.email.label'),
61
+ queue: t('trigger-type.queue.label'),
62
+ };
63
+
55
64
  const options = useMemo(
56
65
  () =>
57
66
  Trigger.Kinds.map((kind) => ({
58
67
  value: kind,
59
- label: t(`trigger type ${kind}`),
68
+ label: kindLabels[kind],
60
69
  })),
61
70
  [t],
62
71
  );
63
72
 
64
- return <SelectInput {...props} options={options} onValueChange={handleTypeChange} />;
73
+ return <SelectField {...props} options={options} onValueChange={handleTypeChange} />;
65
74
  };
75
+
76
+ SpecSelector.displayName = 'Form.SpecSelector';
@@ -4,43 +4,45 @@
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useState } from 'react';
7
+ import { expect, userEvent, within } from 'storybook/test';
7
8
 
8
9
  import { Filter, Obj, Ref, Tag, Type } from '@dxos/echo';
9
- import { Function } from '@dxos/functions';
10
10
  import { Trigger } from '@dxos/functions';
11
11
  import { invariant } from '@dxos/invariant';
12
- import { faker } from '@dxos/random';
12
+ import { Operation } from '@dxos/operation';
13
+ import { random } from '@dxos/random';
13
14
  import { useQuery } from '@dxos/react-client/echo';
14
- import { ContactType, useClientProvider, withClientProvider } from '@dxos/react-client/testing';
15
+ import { TestSchema, useClientStory, withClientProvider } from '@dxos/react-client/testing';
15
16
  import { useAsyncEffect } from '@dxos/react-ui';
17
+ import { translations as formTranslations } from '@dxos/react-ui-form';
16
18
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
17
- import { Employer, Organization, Person, Project } from '@dxos/types';
19
+ import { Employer, Organization, Person, Pipeline } from '@dxos/types';
18
20
 
19
- import { functions } from '../../testing';
20
- import { translations } from '../../translations';
21
+ import { functions } from '#testing';
21
22
 
23
+ import { translations } from '../../translations';
22
24
  import { TriggerEditor, type TriggerEditorProps } from './TriggerEditor';
23
25
 
24
26
  const types = [
25
27
  // TODO(burdon): Get label from annotation.
26
28
  { value: Organization.Organization.typename, label: 'Organization' },
27
29
  { value: Person.Person.typename, label: 'Person' },
28
- { value: Type.getTypename(Project.Project), label: 'Project' },
30
+ { value: Type.getTypename(Pipeline.Pipeline), label: 'Project' },
29
31
  { value: Employer.Employer.typename, label: 'Employer' },
30
32
  ];
31
33
 
32
34
  const DefaultStory = (props: Partial<TriggerEditorProps>) => {
33
- const { space } = useClientProvider();
35
+ const { space } = useClientStory();
34
36
  const [trigger, setTrigger] = useState<Trigger.Trigger>();
35
- const tags = useQuery(space, Filter.type(Tag.Tag));
37
+ const tags = useQuery(space?.db, Filter.type(Tag.Tag));
36
38
 
37
39
  useAsyncEffect(async () => {
38
40
  if (!space) {
39
41
  return;
40
42
  }
41
43
 
42
- const result = await space.db.query(Filter.type(Function.Function)).run();
43
- const fn = result.objects.find((fn) => fn.name === 'example.com/function/forex');
44
+ const functions = await space.db.query(Filter.type(Operation.PersistentOperation)).run();
45
+ const fn = functions.find((fn) => fn.name === 'example.com/function/forex');
44
46
  invariant(fn);
45
47
  const trigger = space.db.add(
46
48
  Trigger.make({
@@ -60,42 +62,44 @@ const DefaultStory = (props: Partial<TriggerEditorProps>) => {
60
62
  }
61
63
 
62
64
  return (
63
- <div role='none' className='is-[32rem] bs-fit border border-separator rounded-sm'>
64
- <TriggerEditor
65
- space={space}
66
- trigger={trigger}
67
- types={types}
68
- tags={tags}
69
- onSave={(values) => console.log('on save', values)}
70
- {...props}
71
- />
72
- </div>
65
+ <TriggerEditor
66
+ db={space.db}
67
+ trigger={trigger}
68
+ types={types}
69
+ tags={tags}
70
+ onSave={(values) => console.log('on save', values)}
71
+ {...props}
72
+ />
73
73
  );
74
74
  };
75
75
 
76
76
  const meta = {
77
- title: 'plugins/plugin-automation/TriggerEditor',
77
+ title: 'plugins/plugin-automation/components/TriggerEditor',
78
78
  component: TriggerEditor as any,
79
79
  render: DefaultStory,
80
80
  decorators: [
81
- withTheme,
82
- withLayout({ container: 'column' }),
81
+ withTheme(),
82
+ withLayout({ layout: 'column' }),
83
83
  withClientProvider({
84
84
  createIdentity: true,
85
85
  createSpace: true,
86
- types: [Tag.Tag, Function.Function, Trigger.Trigger, ContactType],
86
+ types: [Tag.Tag, Operation.PersistentOperation, Trigger.Trigger, TestSchema.ContactType],
87
87
  onCreateSpace: ({ space }) => {
88
- space.db.add(Tag.make({ label: 'Important' }));
89
- space.db.add(Tag.make({ label: 'Investor' }));
90
- space.db.add(Tag.make({ label: 'New' }));
88
+ // Tags.
89
+ ['Important', 'Investor', 'New'].forEach((label) => {
90
+ space.db.add(Tag.make({ label }));
91
+ });
92
+
93
+ // Functions.
94
+ functions.forEach((fn) => {
95
+ space.db.add(Obj.make(Operation.PersistentOperation, { ...fn, version: fn.version ?? '0.1.0' }));
96
+ });
91
97
 
92
- for (const fn of functions) {
93
- space.db.add(Function.make(fn));
94
- }
98
+ // Objects.
95
99
  Array.from({ length: 10 }).map(() => {
96
100
  return space.db.add(
97
- Obj.make(ContactType, {
98
- name: faker.person.fullName(),
101
+ Obj.make(TestSchema.ContactType, {
102
+ name: random.person.fullName(),
99
103
  identifiers: [],
100
104
  }),
101
105
  );
@@ -104,7 +108,8 @@ const meta = {
104
108
  }),
105
109
  ],
106
110
  parameters: {
107
- translations,
111
+ layout: 'fullscreen',
112
+ translations: [...formTranslations, ...translations],
108
113
  },
109
114
  } satisfies Meta<typeof DefaultStory>;
110
115
 
@@ -119,3 +124,44 @@ export const ReadonlySpec: Story = {
119
124
  readonlySpec: true,
120
125
  },
121
126
  };
127
+
128
+ export const Spec: Story = {
129
+ play: async ({ canvasElement }) => {
130
+ const canvas = within(canvasElement);
131
+ const webhookText = await canvas.findByText('Webhook', {}, { timeout: 10_000 });
132
+ const combobox = webhookText.closest('[role="combobox"]') as HTMLElement;
133
+ await expect(combobox).not.toBeDisabled();
134
+
135
+ // Helper to switch to a kind via keyboard.
136
+ // TODO(wittjosiah): Radix Select in popper mode doesn't close on click.
137
+ // Use keyboard navigation: open, type first letter to jump, Enter to select.
138
+ const selectKind = async (combobox: HTMLElement, firstLetter: string) => {
139
+ combobox.focus();
140
+ await userEvent.keyboard('{Enter}');
141
+ await userEvent.keyboard(firstLetter);
142
+ await userEvent.keyboard('{Enter}');
143
+ };
144
+
145
+ // Timer — should show "Cron" field.
146
+ await selectKind(combobox, 't');
147
+ await expect(canvas.findByLabelText('Cron')).resolves.toBeInTheDocument();
148
+
149
+ // Email — no extra fields; Cron should be gone.
150
+ await selectKind(combobox, 'e');
151
+ await expect(combobox).not.toBeDisabled();
152
+ await expect(canvas.queryByLabelText('Cron')).not.toBeInTheDocument();
153
+
154
+ // Webhook — should show "Method" field.
155
+ await selectKind(combobox, 'w');
156
+ await expect(canvas.findByLabelText('Method')).resolves.toBeInTheDocument();
157
+
158
+ // Subscription — should show query editor.
159
+ await selectKind(combobox, 's');
160
+ await expect(combobox).not.toBeDisabled();
161
+ await expect(canvas.queryByLabelText('Method')).not.toBeInTheDocument();
162
+
163
+ // Feed — should show DXN field (the queue address). DXN is a combobox, not an input, so use getByText.
164
+ await selectKind(combobox, 'f');
165
+ await expect(canvas.findByText('DXN')).resolves.toBeInTheDocument();
166
+ },
167
+ };
@@ -5,59 +5,87 @@
5
5
  import React, { useCallback, useMemo } from 'react';
6
6
 
7
7
  import { ComputeGraph } from '@dxos/conductor';
8
- import { type Query, Type } from '@dxos/echo';
9
- import { Function, Script, Trigger } from '@dxos/functions';
10
- import { Filter, Ref, type Space, useQuery } from '@dxos/react-client/echo';
8
+ import { DXN, type Database, Entity, Feed, Obj, type Query } from '@dxos/echo';
9
+ import { Script, Trigger } from '@dxos/functions';
10
+ import { Operation } from '@dxos/operation';
11
+ import { Filter, Ref, useQuery } from '@dxos/react-client/echo';
11
12
  import { Input } from '@dxos/react-ui';
12
13
  import { QueryForm, type QueryFormProps } from '@dxos/react-ui-components';
13
- import { type CustomInputMap, Form, InputHeader, SelectInput, useRefQueryLookupHandler } from '@dxos/react-ui-form';
14
-
15
- import { FunctionInputEditor, type FunctionInputEditorProps } from './FunctionInputEditor';
14
+ import {
15
+ type ExcludeId,
16
+ Form,
17
+ FormFieldLabel,
18
+ type FormFieldMap,
19
+ type FormRootProps,
20
+ SelectField,
21
+ omitId,
22
+ } from '@dxos/react-ui-form';
23
+
24
+ import { FunctionInputEditor } from './FunctionInputEditor';
16
25
  import { SpecSelector } from './SpecSelector';
17
26
 
27
+ type TriggerFormSchema = ExcludeId<typeof Trigger.Trigger>;
28
+
18
29
  export type TriggerEditorProps = {
19
- space: Space;
30
+ db: Database.Database;
20
31
  trigger: Trigger.Trigger;
21
32
  // TODO(wittjosiah): This needs to apply to whole spec but currently only applies to spec.kind & spec.query.
22
33
  readonlySpec?: boolean;
23
- onSave?: (trigger: Omit<Trigger.Trigger, 'id'>) => void;
24
- onCancel?: () => void;
25
- } & Pick<QueryFormProps, 'types' | 'tags'>;
26
-
27
- export const TriggerEditor = ({ space, trigger, readonlySpec, types, tags, onSave, onCancel }: TriggerEditorProps) => {
28
- const handleSave = ({ id: _, ...values }: Trigger.Trigger) => {
29
- onSave?.(values);
30
- };
34
+ } &
35
+ // prettier-ignore
36
+ Pick<QueryFormProps, 'types' | 'tags'> &
37
+ Pick<FormRootProps<TriggerFormSchema>, 'onSave' | 'onCancel'>;
38
+
39
+ export const TriggerEditor = ({ db, types, tags, readonlySpec, trigger, ...formProps }: TriggerEditorProps) => {
40
+ const fieldMap = useCustomInputs({ db, types, tags, readonlySpec });
41
+
42
+ const handleValuesChanged = useCallback(
43
+ (newValues: Partial<TriggerFormSchema>) => {
44
+ Obj.change(trigger, (obj) => {
45
+ Object.assign(obj, newValues);
46
+ });
47
+ },
48
+ [trigger],
49
+ );
31
50
 
32
- const handleRefQueryLookup = useRefQueryLookupHandler({ space });
33
- const Custom = useCustomInputs({ space, readonlySpec, types, tags, onQueryRefOptions: handleRefQueryLookup });
51
+ const triggerSchema = useMemo(() => omitId(Trigger.Trigger), []);
52
+ const defaultValues = useMemo(() => {
53
+ const { id: _, ...values } = trigger;
54
+ return values;
55
+ }, [trigger]);
34
56
 
35
57
  return (
36
- <Form
37
- outerSpacing={false}
38
- Custom={Custom}
39
- schema={Trigger.Trigger}
40
- values={trigger}
41
- onSave={handleSave}
42
- onCancel={onCancel}
43
- onQueryRefOptions={handleRefQueryLookup}
44
- />
58
+ <Form.Root<TriggerFormSchema>
59
+ {...formProps}
60
+ db={db}
61
+ schema={triggerSchema}
62
+ defaultValues={defaultValues}
63
+ fieldMap={fieldMap}
64
+ onValuesChanged={handleValuesChanged}
65
+ >
66
+ <Form.Viewport>
67
+ <Form.Content>
68
+ <Form.FieldSet />
69
+ <Form.Actions />
70
+ </Form.Content>
71
+ </Form.Viewport>
72
+ </Form.Root>
45
73
  );
46
74
  };
47
75
 
48
76
  type UseCustomInputsProps = {
49
- space: Space;
77
+ db: Database.Database;
50
78
  readonlySpec?: boolean;
51
- onQueryRefOptions: FunctionInputEditorProps['onQueryRefOptions'];
52
79
  } & Pick<QueryFormProps, 'types' | 'tags'>;
53
80
 
54
- const useCustomInputs = ({ space, readonlySpec, types, tags, onQueryRefOptions }: UseCustomInputsProps) => {
55
- const functions = useQuery(space, Filter.type(Function.Function));
56
- const workflows = useQuery(space, Filter.type(ComputeGraph));
57
- const scripts = useQuery(space, Filter.type(Script.Script));
81
+ const useCustomInputs = ({ db, readonlySpec, types, tags }: UseCustomInputsProps): FormFieldMap => {
82
+ const functions = useQuery(db, Filter.type(Operation.PersistentOperation));
83
+ const workflows = useQuery(db, Filter.type(ComputeGraph));
84
+ const scripts = useQuery(db, Filter.type(Script.Script));
85
+ const feeds = useQuery(db, Filter.type(Feed.Feed));
58
86
 
59
87
  return useMemo(
60
- (): CustomInputMap => ({
88
+ (): FormFieldMap => ({
61
89
  // Function selector.
62
90
  ['function' satisfies keyof Trigger.Trigger]: (props) => {
63
91
  const getValue = useCallback(() => {
@@ -70,17 +98,17 @@ const useCustomInputs = ({ space, readonlySpec, types, tags, onQueryRefOptions }
70
98
 
71
99
  const handleOnValueChange = useCallback(
72
100
  (_type: any, dxnString: string) => {
73
- const dxn = Type.DXN.parse(dxnString);
101
+ const dxn = DXN.parse(dxnString);
74
102
  if (dxn) {
75
103
  const ref = Ref.fromDXN(dxn);
76
- props.onValueChange('object', ref);
104
+ props.onValueChange(props.type, ref);
77
105
  }
78
106
  },
79
- [props.onValueChange],
107
+ [props.type, props.onValueChange],
80
108
  );
81
109
 
82
110
  return (
83
- <SelectInput
111
+ <SelectField
84
112
  {...props}
85
113
  getValue={getValue as any}
86
114
  onValueChange={handleOnValueChange}
@@ -90,30 +118,31 @@ const useCustomInputs = ({ space, readonlySpec, types, tags, onQueryRefOptions }
90
118
  },
91
119
 
92
120
  // Spec selector.
93
- ['spec.kind' as const]: (props) => <SpecSelector {...props} readonly={readonlySpec ? 'disabled-input' : false} />,
121
+ 'spec.kind': (props) => <SpecSelector {...props} readonly={readonlySpec} />,
122
+
123
+ // Queue feed selector with parent labels.
124
+ 'spec.queue': (props) => <SelectField {...props} options={getFeedQueueOptions(feeds)} />,
94
125
 
95
126
  // TODO(wittjosiah): Copied from ViewEditor.
96
127
  // Query input editor.
97
- ['spec.query' as const]: (props) => {
128
+ 'spec.query': (props) => {
98
129
  const handleChange = useCallback(
99
- (query: Query.Any) => props.onValueChange('object', { ast: query.ast }),
100
- [props.onValueChange],
130
+ (query: Query.Any) => props.onValueChange(props.type, { ast: query.ast }),
131
+ [props.type, props.onValueChange],
101
132
  );
102
133
 
103
134
  return (
104
135
  <Input.Root>
105
- <InputHeader label={props.label} />
136
+ <FormFieldLabel label={props.label} asChild />
106
137
  <QueryForm initialQuery={(props.getValue() as any).ast} types={types} tags={tags} onChange={handleChange} />
107
138
  </Input.Root>
108
139
  );
109
140
  },
110
141
 
111
142
  // Function input editor.
112
- ['input' as const]: (props) => (
113
- <FunctionInputEditor {...props} functions={functions} onQueryRefOptions={onQueryRefOptions} />
114
- ),
143
+ input: (props) => <FunctionInputEditor {...props} functions={functions} db={db} />,
115
144
  }),
116
- [workflows, scripts, functions, readonlySpec],
145
+ [workflows, scripts, functions, feeds, readonlySpec],
117
146
  );
118
147
  };
119
148
 
@@ -121,7 +150,20 @@ const getWorkflowOptions = (graphs: ComputeGraph[]) => {
121
150
  return graphs.map((graph) => ({ label: `compute-${graph.id}`, value: `dxn:echo:@:${graph.id}` }));
122
151
  };
123
152
 
124
- const getFunctionOptions = (scripts: Script.Script[], functions: Function.Function[]) => {
125
- const getLabel = (fn: Function.Function) => scripts.find((s) => fn.source?.target?.id === s.id)?.name ?? fn.name;
153
+ const getFunctionOptions = (scripts: Script.Script[], functions: Operation.PersistentOperation[]) => {
154
+ const getLabel = (fn: Operation.PersistentOperation) =>
155
+ scripts.find((s) => fn.source?.target?.id === s.id)?.name ?? fn.name;
126
156
  return functions.map((fn) => ({ label: getLabel(fn), value: `dxn:echo:@:${fn.id}` }));
127
157
  };
158
+
159
+ const getFeedQueueOptions = (feeds: Feed.Feed[]) => {
160
+ return feeds.flatMap((feed) => {
161
+ const queueDxn = Feed.getQueueDxn(feed);
162
+ if (!queueDxn) {
163
+ return [];
164
+ }
165
+ const parent = Obj.getParent(feed);
166
+ const label = parent ? Entity.getLabel(parent) : Entity.getLabel(feed);
167
+ return [{ label: label ?? feed.id, value: queueDxn.toString() }];
168
+ });
169
+ };
@@ -7,6 +7,5 @@ import { lazy } from 'react';
7
7
  export * from './TriggerEditor';
8
8
 
9
9
  export const AutomationPanel = lazy(() => import('./AutomationPanel'));
10
- export const AutomationSettings = lazy(() => import('./AutomationSettings'));
11
- export const FunctionsContainer = lazy(() => import('./FunctionsContainer'));
12
10
  export const FunctionsPanel = lazy(() => import('./FunctionsPanel'));
11
+ export const FunctionsRegistry = lazy(() => import('./FunctionsRegistry'));
@@ -0,0 +1,28 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useTranslation } from '@dxos/react-ui';
8
+ import { Settings } from '@dxos/react-ui-form';
9
+
10
+ import { meta } from '#meta';
11
+
12
+ import { AutomationPanel, type AutomationPanelProps } from '../../components/AutomationPanel';
13
+ import { TriggersSettings } from '../TriggerSettings';
14
+
15
+ export const AutomationSettings = (props: AutomationPanelProps) => {
16
+ const { t } = useTranslation(meta.id);
17
+ return (
18
+ <Settings.Viewport>
19
+ <Settings.Section
20
+ title={t('automation-verbose.label', { ns: meta.id })}
21
+ description={t('automation.description', { ns: meta.id })}
22
+ >
23
+ <AutomationPanel {...props} />
24
+ <TriggersSettings db={props.space.db} />
25
+ </Settings.Section>
26
+ </Settings.Viewport>
27
+ );
28
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { AutomationSettings as default } from './AutomationSettings';
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { type Space } from '@dxos/react-client/echo';
8
+ import { useTranslation } from '@dxos/react-ui';
9
+ import { Settings } from '@dxos/react-ui-form';
10
+
11
+ import { meta } from '#meta';
12
+
13
+ import { FunctionsPanel } from '../../components/FunctionsPanel';
14
+ import { FunctionsRegistry } from '../../components/FunctionsRegistry';
15
+
16
+ export const FunctionsContainer = ({ space }: { space: Space }) => {
17
+ const { t } = useTranslation(meta.id);
18
+ return (
19
+ <Settings.Viewport>
20
+ <Settings.Section
21
+ title={t('functions-verbose.label', { ns: meta.id })}
22
+ description={t('functions.description', { ns: meta.id })}
23
+ >
24
+ <FunctionsPanel space={space} />
25
+ </Settings.Section>
26
+ <Settings.Section
27
+ title={t('functions-registry-verbose.label', { ns: meta.id })}
28
+ description={t('functions-registry.description', { ns: meta.id })}
29
+ >
30
+ <FunctionsRegistry space={space} />
31
+ </Settings.Section>
32
+ </Settings.Viewport>
33
+ );
34
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { FunctionsContainer as default } from './FunctionsContainer';
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { type Database } from '@dxos/echo';
8
+ import { Input, useTranslation } from '@dxos/react-ui';
9
+ import { Settings } from '@dxos/react-ui-form';
10
+
11
+ import { useTriggerRuntimeControls } from '#hooks';
12
+ import { meta } from '#meta';
13
+
14
+ export const TriggersSettings = ({ db }: { db: Database.Database }) => {
15
+ const { state, start, stop } = useTriggerRuntimeControls(db);
16
+ const isRunning = state?.enabled ?? false;
17
+ const { t } = useTranslation(meta.id);
18
+
19
+ return (
20
+ <div className='grid grid-cols-1 md:grid-cols-[1fr_min-content]'>
21
+ <Settings.Item title={t('runtime.label')} description={t('runtime.description')}>
22
+ <Input.Switch classNames='justify-self-end' checked={isRunning} onCheckedChange={isRunning ? stop : start} />
23
+ </Settings.Item>
24
+ </div>
25
+ );
26
+ };