windmill-components 1.687.0 → 1.695.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 (264) hide show
  1. package/package/components/ArgInput.svelte +2 -0
  2. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  3. package/package/components/CompareWorkspaces.svelte +206 -157
  4. package/package/components/DatatableSchemaDiff.svelte +2 -2
  5. package/package/components/Dev.svelte +401 -85
  6. package/package/components/EditableSchemaForm.svelte +4 -0
  7. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  8. package/package/components/FlowPreviewContent.svelte +32 -30
  9. package/package/components/FlowRestartButton.svelte +143 -61
  10. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  11. package/package/components/FlowStatusViewer.svelte +15 -1
  12. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  13. package/package/components/FlowStatusViewerInner.svelte +1 -2
  14. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  15. package/package/components/ForkConflictModal.svelte +57 -0
  16. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  17. package/package/components/GitRepoViewer.svelte +251 -97
  18. package/package/components/InputTransformSchemaForm.svelte +1 -1
  19. package/package/components/InstanceSettings.svelte +36 -16
  20. package/package/components/Login.svelte +113 -28
  21. package/package/components/Login.svelte.d.ts +1 -0
  22. package/package/components/Path.svelte +7 -1
  23. package/package/components/Path.svelte.d.ts +1 -1
  24. package/package/components/RunsPage.svelte +2 -1
  25. package/package/components/S3FilePickerInner.svelte +89 -89
  26. package/package/components/ScriptEditor.svelte +18 -5
  27. package/package/components/ShareModal.svelte.d.ts +1 -1
  28. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  29. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  30. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  31. package/package/components/apps/editor/appPolicy.js +2 -1
  32. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  33. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  34. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  35. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  36. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  37. package/package/components/apps/inputType.d.ts +1 -0
  38. package/package/components/apps/sharedTypes.d.ts +1 -0
  39. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  40. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  41. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  42. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  43. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  44. package/package/components/copilot/chat/AIChatManager.svelte.js +48 -46
  45. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  46. package/package/components/copilot/chat/app/core.d.ts +12 -20
  47. package/package/components/copilot/chat/app/core.js +103 -160
  48. package/package/components/copilot/chat/app/core.test.js +234 -9
  49. package/package/components/copilot/chat/context.js +44 -0
  50. package/package/components/copilot/chat/flow/FlowAIChat.svelte +5 -3
  51. package/package/components/copilot/chat/flow/core.d.ts +2 -1
  52. package/package/components/copilot/chat/flow/core.js +48 -21
  53. package/package/components/copilot/chat/flow/helperUtils.d.ts +5 -2
  54. package/package/components/copilot/chat/flow/helperUtils.js +33 -1
  55. package/package/components/copilot/chat/flow/helperUtils.test.js +116 -1
  56. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  57. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  58. package/package/components/copilot/chat/script/core.js +3 -0
  59. package/package/components/copilot/chat/shared.d.ts +6 -0
  60. package/package/components/copilot/chat/shared.js +22 -1
  61. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  62. package/package/components/copilot/chat/shared.test.js +412 -0
  63. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  64. package/package/components/copilot/chat/workspaceTools.js +239 -0
  65. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  66. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  67. package/package/components/copilot/lib.js +3 -1
  68. package/package/components/copilot/lib.test.d.ts +1 -0
  69. package/package/components/copilot/lib.test.js +19 -0
  70. package/package/components/copilot/modelConfig.d.ts +3 -0
  71. package/package/components/copilot/modelConfig.js +10 -0
  72. package/package/components/flows/FlowProgressBar.svelte +5 -2
  73. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  74. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  75. package/package/components/flows/flowStateUtils.svelte.js +5 -1
  76. package/package/components/flows/map/FlowModuleSchemaMap.svelte +3 -2
  77. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -0
  78. package/package/components/git_sync/GitSyncContext.svelte.js +0 -2
  79. package/package/components/graph/FlowGraphV2.svelte +7 -3
  80. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  81. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -0
  82. package/package/components/home/deploy_ui.js +1 -1
  83. package/package/components/icons/AzureIcon.svelte +12 -25
  84. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  85. package/package/components/instanceSettings.js +24 -0
  86. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  87. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  88. package/package/components/offboarding-utils.js +2 -0
  89. package/package/components/progressBar/ProgressBar.svelte +9 -5
  90. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  91. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  92. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  93. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  94. package/package/components/raw_apps/RawAppEditor.svelte +159 -102
  95. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  96. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  97. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  98. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  99. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  100. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  101. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  102. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  103. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  104. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  105. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  106. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  107. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  108. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  109. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  110. package/package/components/resources/resourceTypesFilter.js +21 -0
  111. package/package/components/restartFromStepPath.d.ts +39 -0
  112. package/package/components/restartFromStepPath.js +89 -0
  113. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  114. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  115. package/package/components/runs/JobDetailHeader.svelte +24 -3
  116. package/package/components/runs/runsFilter.d.ts +1 -1
  117. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  118. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  119. package/package/components/search/GlobalSearchModal.svelte +8 -1
  120. package/package/components/select/Select.svelte +1 -1
  121. package/package/components/settings/CreateToken.svelte +48 -77
  122. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  123. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  124. package/package/components/settings/ScopesPicker.svelte +43 -0
  125. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  126. package/package/components/settings/TokensTable.svelte +51 -15
  127. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  128. package/package/components/sidebar/SidebarContent.svelte +11 -1
  129. package/package/components/triggers/AddTriggersButton.svelte +6 -0
  130. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  131. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  132. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  133. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  134. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  135. package/package/components/triggers/TriggersEditor.svelte +5 -1
  136. package/package/components/triggers/TriggersWrapper.svelte +10 -0
  137. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  138. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  139. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  140. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  141. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  142. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  143. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  144. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  145. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  146. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  147. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  148. package/package/components/triggers/azure/utils.js +56 -0
  149. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +2 -0
  150. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +9 -3
  151. package/package/components/triggers/http/RouteEditorInner.svelte +2 -0
  152. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +9 -3
  153. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +9 -3
  154. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +9 -3
  155. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +9 -3
  156. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +9 -3
  157. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +9 -3
  158. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  159. package/package/components/triggers/triggers.svelte.js +23 -1
  160. package/package/components/triggers/utils.js +20 -0
  161. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +9 -3
  162. package/package/components/triggers.d.ts +1 -1
  163. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  164. package/package/components/useNestedRestartState.svelte.js +320 -0
  165. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  166. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  167. package/package/gen/core/OpenAPI.js +1 -1
  168. package/package/gen/schemas.gen.d.ts +294 -24
  169. package/package/gen/schemas.gen.js +297 -25
  170. package/package/gen/services.gen.d.ts +247 -4
  171. package/package/gen/services.gen.js +498 -7
  172. package/package/gen/types.gen.d.ts +990 -37
  173. package/package/hubPaths.json +2 -5
  174. package/package/infer.d.ts +1 -1
  175. package/package/infer.js +37 -51
  176. package/package/mcpEndpointTools.js +60 -4
  177. package/package/script_helpers.js +17 -0
  178. package/package/stores.d.ts +7 -0
  179. package/package/stores.js +6 -1
  180. package/package/system_prompts/index.d.ts +1 -0
  181. package/package/system_prompts/index.js +8 -0
  182. package/package/system_prompts/prompts.d.ts +16 -13
  183. package/package/system_prompts/prompts.js +653 -43
  184. package/package/templates/ci_test_bun.ts.template +8 -0
  185. package/package/templates/ci_test_python.py.template +8 -0
  186. package/package/utils/forkConflict.d.ts +26 -0
  187. package/package/utils/forkConflict.js +56 -0
  188. package/package/utils_deployable.d.ts +164 -121
  189. package/package/utils_deployable.js +61 -11
  190. package/package/utils_workspace_deploy.js +3 -1
  191. package/package.json +29 -5
  192. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  193. package/dist/sharedUtils/base.d.ts +0 -1
  194. package/dist/sharedUtils/cloud.d.ts +0 -1
  195. package/dist/sharedUtils/common.d.ts +0 -111
  196. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  197. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  198. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  199. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  200. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  201. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  202. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  203. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  204. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  205. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  206. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  207. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  208. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  209. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  210. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  211. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  212. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  213. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  214. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  215. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  216. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  217. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  218. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  219. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  220. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  221. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  222. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  223. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  224. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  225. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  226. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  227. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  228. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  229. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  230. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  231. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  232. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  233. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  234. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  235. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  236. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  237. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  238. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  239. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  240. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  241. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  242. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  243. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  244. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  245. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  246. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  247. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  248. package/dist/sharedUtils/gen/index.d.ts +0 -6
  249. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  250. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  251. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  252. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  253. package/dist/sharedUtils/hub.d.ts +0 -49
  254. package/dist/sharedUtils/jsr.json +0 -6
  255. package/dist/sharedUtils/lib.d.ts +0 -5
  256. package/dist/sharedUtils/lib.es.js +0 -1588
  257. package/dist/sharedUtils/package.json +0 -12
  258. package/dist/sharedUtils/schema.d.ts +0 -3
  259. package/dist/sharedUtils/stores.d.ts +0 -97
  260. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  261. package/dist/sharedUtils/toast.d.ts +0 -8
  262. package/dist/sharedUtils/utils.d.ts +0 -265
  263. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  264. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
@@ -0,0 +1,422 @@
1
+ <script lang="ts">import { Alert, Button } from '../../common';
2
+ import Drawer from '../../common/drawer/Drawer.svelte';
3
+ import DrawerContent from '../../common/drawer/DrawerContent.svelte';
4
+ import Path from '../../Path.svelte';
5
+ import { usedTriggerKinds, userStore, workspaceStore } from '../../../stores';
6
+ import { canWrite, capitalize, emptyString, sendUserToast } from '../../../utils';
7
+ import { withForkConflictRetry } from '../../../utils/forkConflict';
8
+ import { Loader2 } from 'lucide-svelte';
9
+ import Label from '../../Label.svelte';
10
+ import { AzureTriggerService } from '../../../gen';
11
+ import Section from '../../Section.svelte';
12
+ import ScriptPicker from '../../ScriptPicker.svelte';
13
+ import Required from '../../Required.svelte';
14
+ import AzureTriggerEditorConfigSection from './AzureTriggerEditorConfigSection.svelte';
15
+ import { untrack } from 'svelte';
16
+ import TriggerEditorToolbar from '../TriggerEditorToolbar.svelte';
17
+ import PermissionedAsLine from '../PermissionedAsLine.svelte';
18
+ import { saveAzureTriggerFromCfg } from './utils';
19
+ import { getHandlerType, handleConfigChange } from '../utils';
20
+ import { deepEqual } from 'fast-equals';
21
+ import TriggerSuspendedJobsAlert from '../TriggerSuspendedJobsAlert.svelte';
22
+ import TriggerSuspendedJobsModal from '../TriggerSuspendedJobsModal.svelte';
23
+ import { base } from '../../../base';
24
+ import Tabs from '../../common/tabs/Tabs.svelte';
25
+ import Tab from '../../common/tabs/Tab.svelte';
26
+ import TriggerRetriesAndErrorHandler from '../TriggerRetriesAndErrorHandler.svelte';
27
+ import TriggerAdvancedBadges from '../TriggerAdvancedBadges.svelte';
28
+ let drawer = $state(undefined);
29
+ let initialPath = $state('');
30
+ let edit = $state(true);
31
+ let itemKind = $state('script');
32
+ let script_path = $state('');
33
+ let initialScriptPath = $state('');
34
+ let fixedScriptPath = $state('');
35
+ let path = $state('');
36
+ let pathError = $state('');
37
+ let mode = $state('enabled');
38
+ let dirtyPath = $state(false);
39
+ let can_write = $state(true);
40
+ let drawerLoading = $state(true);
41
+ let azure_resource_path = $state('');
42
+ let azure_mode = $state('namespace_pull');
43
+ let scope_resource_id = $state('');
44
+ let topic_name = $state(undefined);
45
+ let subscription_name = $state('');
46
+ let event_type_filters = $state(undefined);
47
+ let isValid = $state(false);
48
+ let initialConfig = undefined;
49
+ let deploymentLoading = $state(false);
50
+ let permissionedAs = $state(undefined);
51
+ let selectedPermissionedAs = $state(undefined);
52
+ let preservePermissionedAs = $state(false);
53
+ let base_endpoint = $derived(`${window.location.origin}${base}`);
54
+ let optionTabSelected = $state('error_handler');
55
+ let errorHandlerSelected = $state('slack');
56
+ let error_handler_path = $state();
57
+ let error_handler_args = $state({});
58
+ let retry = $state();
59
+ let suspendedJobsModal = $state(null);
60
+ let originalConfig = $state(undefined);
61
+ let { useDrawer = true, description = undefined, hideTarget = false, hideTooltips = false, isEditor = false, allowDraft = false, trigger = undefined, isDeployed = false, customLabel = undefined, onConfigChange = undefined, onCaptureConfigChange = undefined, onUpdate = undefined, onDelete = undefined, onReset = undefined, cloudDisabled = false } = $props();
62
+ let hasChanged = $derived(!deepEqual(getAzureConfig(), originalConfig ?? {}));
63
+ const azureConfig = $derived.by(getAzureConfig);
64
+ const saveDisabled = $derived(pathError != '' || emptyString(script_path) || !isValid || !can_write || !hasChanged);
65
+ const captureConfig = $derived.by(untrack(() => isEditor) ? getAzureCaptureConfig : () => ({}));
66
+ export async function openEdit(ePath, isFlow, defaultValues) {
67
+ drawerLoading = true;
68
+ try {
69
+ drawer?.openDrawer();
70
+ initialPath = ePath;
71
+ itemKind = isFlow ? 'flow' : 'script';
72
+ edit = true;
73
+ dirtyPath = false;
74
+ await loadTrigger(defaultValues);
75
+ originalConfig = structuredClone($state.snapshot(getAzureConfig()));
76
+ }
77
+ catch (err) {
78
+ sendUserToast(`Could not load Azure trigger: ${err.body}`, true);
79
+ }
80
+ finally {
81
+ drawerLoading = false;
82
+ if (!defaultValues) {
83
+ initialConfig = structuredClone($state.snapshot(getAzureConfig()));
84
+ }
85
+ }
86
+ }
87
+ export async function openNew(nis_flow, fixedScriptPath_, defaultValues) {
88
+ drawerLoading = true;
89
+ try {
90
+ drawer?.openDrawer();
91
+ itemKind = nis_flow ? 'flow' : 'script';
92
+ initialScriptPath = '';
93
+ fixedScriptPath = fixedScriptPath_ ?? '';
94
+ script_path = fixedScriptPath;
95
+ azure_resource_path = defaultValues?.azure_resource_path ?? '';
96
+ azure_mode = defaultValues?.azure_mode ?? 'namespace_pull';
97
+ scope_resource_id = defaultValues?.scope_resource_id ?? '';
98
+ topic_name = defaultValues?.topic_name ?? undefined;
99
+ subscription_name = defaultValues?.subscription_name ?? '';
100
+ event_type_filters = defaultValues?.event_type_filters ?? undefined;
101
+ path = defaultValues?.path ?? '';
102
+ initialPath = '';
103
+ edit = false;
104
+ dirtyPath = false;
105
+ mode = defaultValues?.mode ?? 'enabled';
106
+ error_handler_path = defaultValues?.error_handler_path ?? undefined;
107
+ error_handler_args = defaultValues?.error_handler_args ?? {};
108
+ retry = defaultValues?.retry ?? undefined;
109
+ errorHandlerSelected = getHandlerType(error_handler_path ?? '');
110
+ permissionedAs = undefined;
111
+ selectedPermissionedAs = undefined;
112
+ preservePermissionedAs = false;
113
+ originalConfig = undefined;
114
+ }
115
+ finally {
116
+ drawerLoading = false;
117
+ }
118
+ }
119
+ async function loadTrigger(defaultConfig) {
120
+ if (defaultConfig) {
121
+ loadTriggerConfig(defaultConfig);
122
+ return;
123
+ }
124
+ try {
125
+ const s = await AzureTriggerService.getAzureTrigger({
126
+ workspace: $workspaceStore,
127
+ path: initialPath
128
+ });
129
+ loadTriggerConfig(s);
130
+ }
131
+ catch (error) {
132
+ sendUserToast(`Could not load Azure trigger: ${error.body}`, true);
133
+ }
134
+ }
135
+ async function loadTriggerConfig(cfg) {
136
+ script_path = cfg?.script_path;
137
+ initialScriptPath = cfg?.script_path;
138
+ azure_resource_path = cfg?.azure_resource_path;
139
+ azure_mode = cfg?.azure_mode;
140
+ scope_resource_id = cfg?.scope_resource_id;
141
+ topic_name = cfg?.topic_name ?? undefined;
142
+ subscription_name = cfg?.subscription_name;
143
+ event_type_filters = cfg?.event_type_filters;
144
+ path = cfg?.path;
145
+ mode = cfg?.mode ?? 'enabled';
146
+ can_write = canWrite(cfg?.path, cfg?.extra_perms, $userStore);
147
+ error_handler_path = cfg?.error_handler_path;
148
+ error_handler_args = cfg?.error_handler_args ?? {};
149
+ retry = cfg?.retry;
150
+ errorHandlerSelected = getHandlerType(error_handler_path ?? '');
151
+ permissionedAs = cfg?.permissioned_as;
152
+ selectedPermissionedAs = cfg?.permissioned_as;
153
+ preservePermissionedAs = !!cfg?.permissioned_as;
154
+ }
155
+ async function updateTrigger() {
156
+ deploymentLoading = true;
157
+ const cfg = azureConfig;
158
+ if (!cfg)
159
+ return;
160
+ const isSaved = await saveAzureTriggerFromCfg(initialPath, cfg, edit, $workspaceStore, usedTriggerKinds);
161
+ if (isSaved) {
162
+ onUpdate?.(cfg.path);
163
+ originalConfig = structuredClone($state.snapshot(getAzureConfig()));
164
+ initialPath = cfg.path;
165
+ initialScriptPath = cfg.script_path;
166
+ if (mode !== 'suspended')
167
+ drawer?.closeDrawer();
168
+ }
169
+ deploymentLoading = false;
170
+ }
171
+ function getAzureConfig() {
172
+ return {
173
+ azure_resource_path,
174
+ azure_mode,
175
+ scope_resource_id,
176
+ topic_name,
177
+ subscription_name,
178
+ event_type_filters,
179
+ base_endpoint,
180
+ path,
181
+ script_path,
182
+ mode,
183
+ is_flow: itemKind === 'flow',
184
+ error_handler_path,
185
+ error_handler_args,
186
+ retry,
187
+ permissioned_as: selectedPermissionedAs,
188
+ preserve_permissioned_as: preservePermissionedAs || undefined
189
+ };
190
+ }
191
+ function getAzureCaptureConfig() {
192
+ return {
193
+ azure_resource_path,
194
+ azure_mode,
195
+ scope_resource_id,
196
+ topic_name,
197
+ subscription_name,
198
+ event_type_filters,
199
+ base_endpoint,
200
+ path
201
+ };
202
+ }
203
+ async function handleToggleMode(newMode) {
204
+ const previousMode = mode;
205
+ mode = newMode;
206
+ if (!trigger?.draftConfig) {
207
+ const ok = await withForkConflictRetry((force) => AzureTriggerService.setAzureTriggerMode({
208
+ path: initialPath,
209
+ workspace: $workspaceStore ?? '',
210
+ requestBody: { mode: newMode, force }
211
+ }), 'Azure trigger');
212
+ if (!ok) {
213
+ mode = previousMode;
214
+ return;
215
+ }
216
+ sendUserToast(`${capitalize(newMode)} Azure trigger ${initialPath}`);
217
+ onUpdate?.(initialPath);
218
+ }
219
+ if (originalConfig)
220
+ originalConfig['mode'] = newMode;
221
+ }
222
+ $effect(() => {
223
+ if (!drawerLoading) {
224
+ handleConfigChange(azureConfig, initialConfig, saveDisabled, edit, onConfigChange);
225
+ }
226
+ });
227
+ $effect(() => {
228
+ const args = [captureConfig, isValid];
229
+ untrack(() => onCaptureConfigChange?.(...args));
230
+ });
231
+ </script>
232
+
233
+ {#if mode === 'suspended'}
234
+ <TriggerSuspendedJobsModal
235
+ bind:this={suspendedJobsModal}
236
+ triggerPath={path}
237
+ triggerKind="azure"
238
+ {hasChanged}
239
+ onToggleMode={handleToggleMode}
240
+ runnableConfig={{
241
+ path: script_path,
242
+ kind: itemKind,
243
+ retry,
244
+ errorHandlerPath: error_handler_path,
245
+ errorHandlerArgs: error_handler_args
246
+ }}
247
+ />
248
+ {/if}
249
+
250
+ {#if useDrawer}
251
+ <Drawer size="800px" bind:this={drawer}>
252
+ <DrawerContent
253
+ title={edit
254
+ ? can_write
255
+ ? `Edit Azure trigger ${initialPath}`
256
+ : `Azure trigger ${initialPath}`
257
+ : 'New Azure trigger'}
258
+ on:close={drawer?.closeDrawer}
259
+ >
260
+ {#snippet actions()}
261
+ {@render actionsButtons()}
262
+ {/snippet}
263
+ {@render config()}
264
+ </DrawerContent>
265
+ </Drawer>
266
+ {:else}
267
+ <Section
268
+ label={!customLabel ? 'Azure Event Grid trigger' : ''}
269
+ headerClass="grow min-w-0 h-[30px]"
270
+ >
271
+ {#snippet header()}
272
+ {#if customLabel}
273
+ {@render customLabel()}
274
+ {/if}
275
+ {/snippet}
276
+ {#snippet action()}
277
+ {@render actionsButtons()}
278
+ {/snippet}
279
+ {@render config()}
280
+ </Section>
281
+ {/if}
282
+
283
+ {#snippet actionsButtons()}
284
+ {#if !drawerLoading && can_write}
285
+ <TriggerEditorToolbar
286
+ permissions={drawerLoading || !can_write ? 'none' : 'create'}
287
+ {saveDisabled}
288
+ {mode}
289
+ isLoading={deploymentLoading}
290
+ {edit}
291
+ {allowDraft}
292
+ {isDeployed}
293
+ onUpdate={updateTrigger}
294
+ {onReset}
295
+ {onDelete}
296
+ onToggleMode={handleToggleMode}
297
+ {cloudDisabled}
298
+ {trigger}
299
+ {suspendedJobsModal}
300
+ />
301
+ {/if}
302
+ {/snippet}
303
+
304
+ {#snippet config()}
305
+ {#if drawerLoading}
306
+ <div class="flex flex-col items-center justify-center h-full w-full">
307
+ <Loader2 size="50" class="animate-spin" />
308
+ <p>Loading...</p>
309
+ </div>
310
+ {:else}
311
+ <PermissionedAsLine
312
+ {permissionedAs}
313
+ {path}
314
+ onPermissionedAsChange={(pa, preserve) => {
315
+ selectedPermissionedAs = pa
316
+ preservePermissionedAs = preserve
317
+ }}
318
+ />
319
+ <div class="flex flex-col gap-5">
320
+ {#if mode === 'suspended'}
321
+ <TriggerSuspendedJobsAlert {suspendedJobsModal} />
322
+ {/if}
323
+ {#if description}
324
+ {@render description()}
325
+ {/if}
326
+ {#if !hideTooltips}
327
+ <Alert title="Info" type="info">
328
+ {#if edit}
329
+ Changes can take up to 30 seconds to take effect.
330
+ {:else}
331
+ New Azure triggers can take up to 30 seconds to start listening.
332
+ {/if}
333
+ </Alert>
334
+ {/if}
335
+ </div>
336
+ <div class="flex flex-col gap-12 mt-6">
337
+ <div class="flex flex-col gap-4">
338
+ <Label label="Path">
339
+ <Path
340
+ bind:dirty={dirtyPath}
341
+ bind:error={pathError}
342
+ bind:path
343
+ {initialPath}
344
+ checkInitialPathExistence={!edit}
345
+ namePlaceholder="azure_trigger"
346
+ kind="azure_trigger"
347
+ disabled={!can_write}
348
+ disableEditing={!can_write}
349
+ />
350
+ </Label>
351
+ </div>
352
+
353
+ {#if !hideTarget}
354
+ <Section label="Runnable">
355
+ <p class="text-xs mb-1 text-primary">
356
+ Pick a script or flow to be triggered <Required required={true} />
357
+ </p>
358
+ <div class="flex flex-row mb-2">
359
+ <ScriptPicker
360
+ disabled={fixedScriptPath != '' || !can_write}
361
+ initialPath={fixedScriptPath || initialScriptPath}
362
+ kinds={['script']}
363
+ allowFlow={true}
364
+ bind:itemKind
365
+ bind:scriptPath={script_path}
366
+ allowRefresh={can_write}
367
+ allowEdit={!$userStore?.operator}
368
+ clearable
369
+ />
370
+ {#if emptyString(script_path)}
371
+ <Button
372
+ btnClasses="ml-4"
373
+ variant="default"
374
+ unifiedSize="md"
375
+ disabled={!can_write}
376
+ href={itemKind === 'flow' ? '/flows/add?hub=81' : '/scripts/add?hub=hub%2F28214'}
377
+ target="_blank">Create from template</Button
378
+ >
379
+ {/if}
380
+ </div>
381
+ </Section>
382
+ {/if}
383
+
384
+ <AzureTriggerEditorConfigSection
385
+ bind:isValid
386
+ bind:azure_resource_path
387
+ bind:azure_mode
388
+ bind:scope_resource_id
389
+ bind:topic_name
390
+ bind:subscription_name
391
+ bind:event_type_filters
392
+ {path}
393
+ {can_write}
394
+ headless={true}
395
+ />
396
+
397
+ <Section label="Advanced" collapsable>
398
+ {#snippet header()}
399
+ <TriggerAdvancedBadges {error_handler_path} {retry} />
400
+ {/snippet}
401
+ <div class="min-h-96">
402
+ <Tabs bind:selected={optionTabSelected}>
403
+ <Tab value="error_handler" label="Error Handler" />
404
+ <Tab value="retries" label="Retries" />
405
+ </Tabs>
406
+ <div class="mt-4">
407
+ <TriggerRetriesAndErrorHandler
408
+ {optionTabSelected}
409
+ {itemKind}
410
+ {can_write}
411
+ bind:errorHandlerSelected
412
+ bind:error_handler_path
413
+ bind:error_handler_args
414
+ bind:retry
415
+ />
416
+ </div>
417
+ </div>
418
+ </Section>
419
+ <div class="pb-8" />
420
+ </div>
421
+ {/if}
422
+ {/snippet}
@@ -0,0 +1,25 @@
1
+ import { type Snippet } from 'svelte';
2
+ import { type Trigger } from '../utils';
3
+ type $$ComponentProps = {
4
+ useDrawer?: boolean;
5
+ description?: Snippet | undefined;
6
+ hideTarget?: boolean;
7
+ hideTooltips?: boolean;
8
+ isEditor?: boolean;
9
+ allowDraft?: boolean;
10
+ trigger?: Trigger;
11
+ isDeployed?: boolean;
12
+ customLabel?: Snippet;
13
+ onConfigChange?: (cfg: Record<string, any>, saveDisabled: boolean, updated: boolean) => void;
14
+ onCaptureConfigChange?: (cfg: Record<string, any>, isValid: boolean) => void;
15
+ onUpdate?: (path?: string) => void;
16
+ onDelete?: () => void;
17
+ onReset?: () => void;
18
+ cloudDisabled?: boolean;
19
+ };
20
+ declare const AzureTriggerEditorInner: import("svelte").Component<$$ComponentProps, {
21
+ openEdit: (ePath: string, isFlow: boolean, defaultValues?: Record<string, any>) => Promise<void>;
22
+ openNew: (nis_flow: boolean, fixedScriptPath_?: string, defaultValues?: Record<string, any>) => Promise<void>;
23
+ }, "">;
24
+ type AzureTriggerEditorInner = ReturnType<typeof AzureTriggerEditorInner>;
25
+ export default AzureTriggerEditorInner;
@@ -0,0 +1,55 @@
1
+ <script lang="ts">import { isCloudHosted } from '../../../cloud';
2
+ import { Alert } from '../../common';
3
+ import Description from '../../Description.svelte';
4
+ import { enterpriseLicense } from '../../../stores';
5
+ import AzureTriggerEditorInner from './AzureTriggerEditorInner.svelte';
6
+ import { onMount } from 'svelte';
7
+ let { selectedTrigger, isFlow, path, isDeployed = false, defaultValues = undefined, customLabel = undefined, ...restProps } = $props();
8
+ let azureTriggerEditor = $state(undefined);
9
+ async function openAzureTriggerEditor(isFlow, isDraft) {
10
+ if (isDraft) {
11
+ azureTriggerEditor?.openNew(isFlow, path, defaultValues);
12
+ }
13
+ else {
14
+ azureTriggerEditor?.openEdit(selectedTrigger.path, isFlow, defaultValues);
15
+ }
16
+ }
17
+ onMount(() => {
18
+ azureTriggerEditor && openAzureTriggerEditor(isFlow, selectedTrigger.isDraft ?? false);
19
+ });
20
+ const cloudDisabled = $derived(isCloudHosted());
21
+ </script>
22
+
23
+ {#if !$enterpriseLicense}
24
+ <Alert title="EE Only" type="warning" size="xs">
25
+ Azure Event Grid triggers are an enterprise only feature.
26
+ </Alert>
27
+ {:else}
28
+ <div class="flex flex-col gap-4">
29
+ <AzureTriggerEditorInner
30
+ bind:this={azureTriggerEditor}
31
+ useDrawer={false}
32
+ hideTarget
33
+ hideTooltips={!isDeployed || cloudDisabled}
34
+ allowDraft={true}
35
+ trigger={selectedTrigger}
36
+ {customLabel}
37
+ {isDeployed}
38
+ {cloudDisabled}
39
+ {...restProps}
40
+ >
41
+ {#snippet description()}
42
+ {#if cloudDisabled}
43
+ <Alert title="Not compatible with multi-tenant cloud" type="warning" size="xs">
44
+ Azure Event Grid triggers are disabled in the multi-tenant cloud.
45
+ </Alert>
46
+ {:else}
47
+ <Description link="https://www.windmill.dev/docs/core_concepts/azure_triggers">
48
+ Azure Event Grid triggers execute scripts and flows in response to events from Azure
49
+ Event Grid (basic) or Event Grid Namespaces (push or pull).
50
+ </Description>
51
+ {/if}
52
+ {/snippet}
53
+ </AzureTriggerEditorInner>
54
+ </div>
55
+ {/if}
@@ -0,0 +1,10 @@
1
+ declare const AzureTriggerPanel: import("svelte").Component<{
2
+ selectedTrigger: any;
3
+ isFlow: any;
4
+ path: any;
5
+ isDeployed?: boolean;
6
+ defaultValues?: any;
7
+ customLabel?: any;
8
+ } & Record<string, any>, {}, "">;
9
+ type AzureTriggerPanel = ReturnType<typeof AzureTriggerPanel>;
10
+ export default AzureTriggerPanel;
@@ -1,2 +1,2 @@
1
1
  import { type Writable } from 'svelte/store';
2
- export declare function saveKafkaTriggerFromCfg(initialPath: string, cfg: Record<string, any>, edit: boolean, workspace: string, usedTriggerKinds: Writable<string[]>): Promise<boolean>;
2
+ export declare function saveAzureTriggerFromCfg(initialPath: string, cfg: Record<string, any>, edit: boolean, workspace: string, usedTriggerKinds: Writable<string[]>): Promise<boolean>;
@@ -0,0 +1,56 @@
1
+ import { AzureTriggerService } from '../../../gen';
2
+ import { sendUserToast } from '../../../toast';
3
+ import { get } from 'svelte/store';
4
+ export async function saveAzureTriggerFromCfg(initialPath, cfg, edit, workspace, usedTriggerKinds) {
5
+ try {
6
+ const errorHandlerAndRetries = !cfg.is_flow
7
+ ? {
8
+ error_handler_path: cfg.error_handler_path,
9
+ error_handler_args: cfg.error_handler_path ? cfg.error_handler_args : undefined,
10
+ retry: cfg.retry
11
+ }
12
+ : {};
13
+ const requestBody = {
14
+ azure_resource_path: cfg.azure_resource_path,
15
+ azure_mode: cfg.azure_mode,
16
+ scope_resource_id: cfg.scope_resource_id,
17
+ topic_name: cfg.topic_name,
18
+ subscription_name: cfg.subscription_name,
19
+ base_endpoint: cfg.base_endpoint,
20
+ event_type_filters: cfg.event_type_filters,
21
+ path: cfg.path,
22
+ script_path: cfg.script_path,
23
+ mode: cfg.mode,
24
+ is_flow: cfg.is_flow,
25
+ permissioned_as: cfg.permissioned_as,
26
+ preserve_permissioned_as: cfg.preserve_permissioned_as,
27
+ ...errorHandlerAndRetries
28
+ };
29
+ if (edit) {
30
+ await AzureTriggerService.updateAzureTrigger({
31
+ workspace,
32
+ path: initialPath,
33
+ requestBody
34
+ });
35
+ sendUserToast(`Azure Event Grid trigger ${cfg.path} updated`);
36
+ }
37
+ else {
38
+ await AzureTriggerService.createAzureTrigger({
39
+ workspace,
40
+ requestBody: {
41
+ ...requestBody,
42
+ mode: 'enabled'
43
+ }
44
+ });
45
+ sendUserToast(`Azure Event Grid trigger ${cfg.path} created`);
46
+ }
47
+ if (!get(usedTriggerKinds).includes('azure')) {
48
+ usedTriggerKinds.update((t) => [...t, 'azure']);
49
+ }
50
+ return true;
51
+ }
52
+ catch (error) {
53
+ sendUserToast(error.body || error.message, true);
54
+ return false;
55
+ }
56
+ }
@@ -207,6 +207,8 @@ function getEmailTriggerConfig() {
207
207
  async function handleToggleMode(newMode) {
208
208
  mode = newMode;
209
209
  if (!trigger?.draftConfig) {
210
+ // Email addresses are always workspace-prefixed (clone filter
211
+ // excludes workspaced_local_part=false) — no fork-conflict warning.
210
212
  await EmailTriggerService.setEmailTriggerMode({
211
213
  path: initialPath,
212
214
  workspace: $workspaceStore ?? '',
@@ -4,6 +4,7 @@ import DrawerContent from '../../common/drawer/DrawerContent.svelte';
4
4
  import Path from '../../Path.svelte';
5
5
  import { usedTriggerKinds, userStore, workspaceStore } from '../../../stores';
6
6
  import { canWrite, capitalize, emptyString, sendUserToast } from '../../../utils';
7
+ import { withForkConflictRetry } from '../../../utils/forkConflict';
7
8
  import { Loader2 } from 'lucide-svelte';
8
9
  import Label from '../../Label.svelte';
9
10
  import { GcpTriggerService } from '../../../gen';
@@ -216,13 +217,18 @@ function getGcpCaptureConfig() {
216
217
  };
217
218
  }
218
219
  async function handleToggleMode(newMode) {
220
+ const previousMode = mode;
219
221
  mode = newMode;
220
222
  if (!trigger?.draftConfig) {
221
- await GcpTriggerService.setGcpTriggerMode({
223
+ const ok = await withForkConflictRetry((force) => GcpTriggerService.setGcpTriggerMode({
222
224
  path: initialPath,
223
225
  workspace: $workspaceStore ?? '',
224
- requestBody: { mode: newMode }
225
- });
226
+ requestBody: { mode: newMode, force }
227
+ }), 'GCP Pub/Sub trigger');
228
+ if (!ok) {
229
+ mode = previousMode;
230
+ return;
231
+ }
226
232
  sendUserToast(`${capitalize(newMode)} GCP Pub/Sub trigger ${initialPath}`);
227
233
  onUpdate?.(initialPath);
228
234
  }
@@ -331,6 +331,8 @@ function getRouteConfig() {
331
331
  async function handleToggleMode(newMode) {
332
332
  mode = newMode;
333
333
  if (!trigger?.draftConfig) {
334
+ // HTTP routes are always workspace-prefixed at runtime, so fork
335
+ // and parent live at distinct URLs — no fork-conflict warning.
334
336
  await HttpTriggerService.setHttpTriggerMode({
335
337
  path: initialPath,
336
338
  workspace: $workspaceStore ?? '',
@@ -8,6 +8,7 @@ import ScriptPicker from '../../ScriptPicker.svelte';
8
8
  import { KafkaTriggerService } from '../../../gen';
9
9
  import { usedTriggerKinds, userStore, workspaceStore } from '../../../stores';
10
10
  import { canWrite, capitalize, emptyString, sendUserToast } from '../../../utils';
11
+ import { withForkConflictRetry } from '../../../utils/forkConflict';
11
12
  import Section from '../../Section.svelte';
12
13
  import { Loader2, RotateCcw } from 'lucide-svelte';
13
14
  import Label from '../../Label.svelte';
@@ -252,13 +253,18 @@ async function resetOffsets() {
252
253
  }
253
254
  }
254
255
  async function handleToggleMode(newMode) {
256
+ const previousMode = mode;
255
257
  mode = newMode;
256
258
  if (!trigger?.draftConfig) {
257
- await KafkaTriggerService.setKafkaTriggerMode({
259
+ const ok = await withForkConflictRetry((force) => KafkaTriggerService.setKafkaTriggerMode({
258
260
  path: initialPath,
259
261
  workspace: $workspaceStore ?? '',
260
- requestBody: { mode: newMode }
261
- });
262
+ requestBody: { mode: newMode, force }
263
+ }), 'Kafka trigger');
264
+ if (!ok) {
265
+ mode = previousMode;
266
+ return;
267
+ }
262
268
  sendUserToast(`${capitalize(newMode)} Kafka trigger ${initialPath}`);
263
269
  onUpdate?.(initialPath);
264
270
  }
@@ -7,6 +7,7 @@ import Required from '../../Required.svelte';
7
7
  import ScriptPicker from '../../ScriptPicker.svelte';
8
8
  import { usedTriggerKinds, userStore, workspaceStore } from '../../../stores';
9
9
  import { canWrite, capitalize, emptyString, sendUserToast } from '../../../utils';
10
+ import { withForkConflictRetry } from '../../../utils/forkConflict';
10
11
  import Section from '../../Section.svelte';
11
12
  import { Loader2 } from 'lucide-svelte';
12
13
  import Label from '../../Label.svelte';
@@ -231,13 +232,18 @@ async function updateTrigger() {
231
232
  deploymentLoading = false;
232
233
  }
233
234
  async function handleToggleMode(newMode) {
235
+ const previousMode = mode;
234
236
  mode = newMode;
235
237
  if (!trigger?.draftConfig) {
236
- await MqttTriggerService.setMqttTriggerMode({
238
+ const ok = await withForkConflictRetry((force) => MqttTriggerService.setMqttTriggerMode({
237
239
  path: initialPath,
238
240
  workspace: $workspaceStore ?? '',
239
- requestBody: { mode: newMode }
240
- });
241
+ requestBody: { mode: newMode, force }
242
+ }), 'MQTT trigger');
243
+ if (!ok) {
244
+ mode = previousMode;
245
+ return;
246
+ }
241
247
  sendUserToast(`${capitalize(newMode)} MQTT trigger ${initialPath}`);
242
248
  onUpdate?.(initialPath);
243
249
  }