windmill-components 1.677.1 → 1.695.0

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 (552) hide show
  1. package/package/components/AppConnectInner.svelte +6 -0
  2. package/package/components/ArgInput.svelte +2 -0
  3. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  4. package/package/components/CiTestResults.svelte +64 -0
  5. package/package/components/CiTestResults.svelte.d.ts +7 -0
  6. package/package/components/CompareWorkspaces.svelte +741 -484
  7. package/package/components/DBManager.svelte +35 -4
  8. package/package/components/DBManager.svelte.d.ts +2 -0
  9. package/package/components/DBManagerContent.svelte +3 -1
  10. package/package/components/DBManagerContent.svelte.d.ts +3 -0
  11. package/package/components/DBManagerDrawer.svelte +145 -3
  12. package/package/components/DBTableEditor.svelte +14 -4
  13. package/package/components/DatatablePicker.svelte +2 -5
  14. package/package/components/DatatableSchemaDiff.svelte +531 -0
  15. package/package/components/DatatableSchemaDiff.svelte.d.ts +29 -0
  16. package/package/components/DedicatedWorkersSelector.svelte +4 -2
  17. package/package/components/DefaultTagsInner.svelte +42 -2
  18. package/package/components/DeployWorkspaceDrawer.svelte +1 -1
  19. package/package/components/Dev.svelte +407 -74
  20. package/package/components/EditableSchemaForm.svelte +4 -0
  21. package/package/components/Editor.svelte +1 -1
  22. package/package/components/EditorBar.svelte +1 -1
  23. package/package/components/EditorBar.svelte.d.ts +1 -1
  24. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  25. package/package/components/FlowPreviewContent.svelte +32 -30
  26. package/package/components/FlowRestartButton.svelte +143 -61
  27. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  28. package/package/components/FlowStatusViewer.svelte +15 -1
  29. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  30. package/package/components/FlowStatusViewerInner.svelte +270 -222
  31. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  32. package/package/components/FlowTimeline.svelte +1 -1
  33. package/package/components/FolderEditor.svelte +189 -4
  34. package/package/components/ForkConflictModal.svelte +57 -0
  35. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  36. package/package/components/ForkWorkspaceBanner.svelte +82 -11
  37. package/package/components/GitRepoViewer.svelte +251 -97
  38. package/package/components/GlobalUserOffboardingModal.svelte +293 -0
  39. package/package/components/GlobalUserOffboardingModal.svelte.d.ts +10 -0
  40. package/package/components/InputTransformSchemaForm.svelte +1 -1
  41. package/package/components/InstanceSettings.svelte +58 -19
  42. package/package/components/Login.svelte +133 -36
  43. package/package/components/Login.svelte.d.ts +1 -0
  44. package/package/components/ModuleTest.svelte +2 -1
  45. package/package/components/NoMainFuncBadge.svelte +1 -1
  46. package/package/components/OffboardItemsBox.svelte +56 -0
  47. package/package/components/OffboardItemsBox.svelte.d.ts +12 -0
  48. package/package/components/OffboardReassignControls.svelte +47 -0
  49. package/package/components/OffboardReassignControls.svelte.d.ts +20 -0
  50. package/package/components/OffboardWorkspaceSection.svelte +110 -0
  51. package/package/components/OffboardWorkspaceSection.svelte.d.ts +24 -0
  52. package/package/components/OnBehalfOfSelector.svelte +21 -3
  53. package/package/components/OnBehalfOfSelector.svelte.d.ts +7 -0
  54. package/package/components/Path.svelte +7 -1
  55. package/package/components/Path.svelte.d.ts +1 -1
  56. package/package/components/QueueAlerts.svelte +10 -10
  57. package/package/components/ResourcePicker.svelte +2 -2
  58. package/package/components/RunsPage.svelte +2 -1
  59. package/package/components/S3FilePickerInner.svelte +89 -89
  60. package/package/components/ScriptBuilder.svelte +52 -11
  61. package/package/components/ScriptEditor.svelte +19 -8
  62. package/package/components/ScriptEditor.svelte.d.ts +1 -1
  63. package/package/components/ShareModal.svelte +236 -98
  64. package/package/components/ShareModal.svelte.d.ts +1 -1
  65. package/package/components/SuperadminSettingsInner.svelte +362 -315
  66. package/package/components/UserOffboardingModal.svelte +238 -0
  67. package/package/components/UserOffboardingModal.svelte.d.ts +10 -0
  68. package/package/components/WorkspaceDeployLayout.svelte +3 -3
  69. package/package/components/WorkspaceDeployLayout.svelte.d.ts +1 -0
  70. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  71. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  72. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  73. package/package/components/apps/editor/appPolicy.js +2 -1
  74. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  75. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  76. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  77. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +4 -2
  78. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  79. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  80. package/package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +12 -0
  81. package/package/components/apps/inputType.d.ts +1 -0
  82. package/package/components/apps/sharedTypes.d.ts +1 -0
  83. package/package/components/assets/AssetsDropdownButton.svelte +1 -1
  84. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  85. package/package/components/common/confirmationModal/ConfirmationModal.svelte +1 -1
  86. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  87. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  88. package/package/components/common/table/AppRow.svelte +3 -3
  89. package/package/components/common/table/FlowRow.svelte +3 -3
  90. package/package/components/common/table/RawAppRow.svelte +4 -4
  91. package/package/components/common/table/Row.svelte +6 -2
  92. package/package/components/common/table/ScriptRow.svelte +11 -3
  93. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  94. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  95. package/package/components/copilot/chat/AIChatManager.svelte.js +50 -48
  96. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  97. package/package/components/copilot/chat/anthropic.d.ts +7 -1
  98. package/package/components/copilot/chat/anthropic.js +5 -2
  99. package/package/components/copilot/chat/app/core.d.ts +12 -20
  100. package/package/components/copilot/chat/app/core.js +230 -159
  101. package/package/components/copilot/chat/app/core.test.js +417 -0
  102. package/package/components/copilot/chat/chatLoop.d.ts +3 -0
  103. package/package/components/copilot/chat/chatLoop.js +13 -5
  104. package/package/components/copilot/chat/context.js +44 -0
  105. package/package/components/copilot/chat/flow/FlowAIChat.svelte +57 -76
  106. package/package/components/copilot/chat/flow/core.d.ts +14 -3
  107. package/package/components/copilot/chat/flow/core.js +494 -116
  108. package/package/components/copilot/chat/flow/helperUtils.d.ts +22 -0
  109. package/package/components/copilot/chat/flow/helperUtils.js +100 -0
  110. package/package/components/copilot/chat/flow/helperUtils.test.js +231 -0
  111. package/package/components/copilot/chat/flow/inlineScriptsUtils.d.ts +5 -24
  112. package/package/components/copilot/chat/flow/inlineScriptsUtils.js +30 -55
  113. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  114. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  115. package/package/components/copilot/chat/flow/utils.test.js +59 -0
  116. package/package/components/copilot/chat/openai-responses.d.ts +7 -1
  117. package/package/components/copilot/chat/openai-responses.js +5 -2
  118. package/package/components/copilot/chat/script/core.js +3 -0
  119. package/package/components/copilot/chat/shared.d.ts +7 -2
  120. package/package/components/copilot/chat/shared.js +116 -53
  121. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  122. package/package/components/copilot/chat/shared.test.js +412 -0
  123. package/package/components/copilot/chat/tokenUsage.d.ts +23 -0
  124. package/package/components/copilot/chat/tokenUsage.js +42 -0
  125. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  126. package/package/components/copilot/chat/workspaceTools.js +239 -0
  127. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  128. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  129. package/package/components/copilot/lib.d.ts +5 -1
  130. package/package/components/copilot/lib.js +24 -6
  131. package/package/components/copilot/lib.test.d.ts +1 -0
  132. package/package/components/copilot/lib.test.js +19 -0
  133. package/package/components/copilot/modelConfig.d.ts +3 -0
  134. package/package/components/copilot/modelConfig.js +10 -0
  135. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte +337 -0
  136. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte.d.ts +15 -0
  137. package/package/components/details/CopyableCodeBlock.svelte +18 -8
  138. package/package/components/details/CopyableCodeBlock.svelte.d.ts +1 -0
  139. package/package/components/flows/FlowAssetsHandler.svelte +19 -21
  140. package/package/components/flows/FlowProgressBar.svelte +5 -2
  141. package/package/components/flows/agentToolTree.d.ts +17 -0
  142. package/package/components/flows/agentToolTree.js +114 -0
  143. package/package/components/flows/agentToolTree.test.d.ts +1 -0
  144. package/package/components/flows/agentToolTree.test.js +86 -0
  145. package/package/components/flows/agentToolUtils.d.ts +0 -5
  146. package/package/components/flows/agentToolUtils.js +0 -49
  147. package/package/components/flows/content/FlowLoop.svelte +7 -4
  148. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  149. package/package/components/flows/content/FlowModuleDeleteAfterUse.svelte +15 -7
  150. package/package/components/flows/content/FlowSettings.svelte +29 -0
  151. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  152. package/package/components/flows/dfs.d.ts +6 -2
  153. package/package/components/flows/dfs.js +19 -11
  154. package/package/components/flows/flowDeleteController.d.ts +32 -0
  155. package/package/components/flows/flowDeleteController.js +54 -0
  156. package/package/components/flows/flowDeleteController.test.d.ts +1 -0
  157. package/package/components/flows/flowDeleteController.test.js +121 -0
  158. package/package/components/flows/flowDeleteUtils.d.ts +48 -0
  159. package/package/components/flows/flowDeleteUtils.js +150 -0
  160. package/package/components/flows/flowDeleteUtils.test.d.ts +1 -0
  161. package/package/components/flows/flowDeleteUtils.test.js +131 -0
  162. package/package/components/flows/flowDiff.d.ts +2 -47
  163. package/package/components/flows/flowDiff.js +16 -293
  164. package/package/components/flows/flowDiff.testUtils.d.ts +8 -0
  165. package/package/components/flows/flowDiff.testUtils.js +26 -0
  166. package/package/components/flows/flowDiffManager.svelte.js +20 -75
  167. package/package/components/flows/flowDiffManager.svelte.test.js +103 -2
  168. package/package/components/flows/flowExplorer.d.ts +4 -0
  169. package/package/components/flows/flowExplorer.js +7 -30
  170. package/package/components/flows/flowState.d.ts +1 -0
  171. package/package/components/flows/flowStateUtils.svelte.js +11 -2
  172. package/package/components/flows/flowTree.d.ts +91 -0
  173. package/package/components/flows/flowTree.js +326 -0
  174. package/package/components/flows/flowTree.test.d.ts +1 -0
  175. package/package/components/flows/flowTree.test.js +236 -0
  176. package/package/components/flows/map/FlowJobsMenu.svelte +36 -30
  177. package/package/components/flows/map/FlowModuleSchemaItem.svelte +1 -1
  178. package/package/components/flows/map/FlowModuleSchemaMap.svelte +73 -229
  179. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -2
  180. package/package/components/flows/pickers/PickHubScriptQuick.svelte +2 -2
  181. package/package/components/flows/previousResults.js +13 -41
  182. package/package/components/flows/previousResults.test.d.ts +1 -0
  183. package/package/components/flows/previousResults.test.js +65 -0
  184. package/package/components/flows/propPicker/OutputPicker.svelte +2 -1
  185. package/package/components/flows/propPicker/OutputPickerInner.svelte +41 -4
  186. package/package/components/flows/propPicker/StepHistory.svelte +9 -1
  187. package/package/components/git_sync/GitSyncContext.svelte.js +11 -7
  188. package/package/components/git_sync/GitSyncRepositoryCard.svelte +2 -29
  189. package/package/components/git_sync/PullWorkspaceModal.svelte +6 -7
  190. package/package/components/graph/FlowGraphV2.svelte +8 -4
  191. package/package/components/graph/FlowGraphV2.svelte.d.ts +2 -0
  192. package/package/components/graph/groupedModulesProxy.svelte.d.ts +10 -0
  193. package/package/components/graph/groupedModulesProxy.svelte.js +17 -1
  194. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +8 -2
  195. package/package/components/home/HomeConnectDrawer.svelte +125 -0
  196. package/package/components/home/HomeConnectDrawer.svelte.d.ts +5 -0
  197. package/package/components/home/deploy_ui.js +1 -1
  198. package/package/components/icons/AzureIcon.svelte +12 -25
  199. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  200. package/package/components/icons/GithubIcon.svelte +4 -4
  201. package/package/components/icons/GithubIcon.svelte.d.ts +5 -2
  202. package/package/components/instanceSettings/ExternalJwtTokens.svelte +85 -0
  203. package/package/components/instanceSettings/ExternalJwtTokens.svelte.d.ts +12 -0
  204. package/package/components/instanceSettings/GhesAppSettings.svelte +17 -0
  205. package/package/components/instanceSettings/IndexerMemorySettings.svelte +56 -29
  206. package/package/components/instanceSettings/SecretBackendConfig.svelte +9 -2
  207. package/package/components/instanceSettings.d.ts +1 -0
  208. package/package/components/instanceSettings.js +66 -8
  209. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  210. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  211. package/package/components/offboarding-utils.d.ts +11 -0
  212. package/package/components/offboarding-utils.js +102 -0
  213. package/package/components/progressBar/ProgressBar.svelte +9 -5
  214. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  215. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  216. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  217. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  218. package/package/components/raw_apps/RawAppDataTableDrawer.svelte +1 -1
  219. package/package/components/raw_apps/RawAppEditor.svelte +186 -102
  220. package/package/components/raw_apps/RawAppEditorHeader.svelte +6 -1
  221. package/package/components/raw_apps/RawAppEditorHeader.svelte.d.ts +1 -0
  222. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  223. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  224. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  225. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  226. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  227. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  228. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  229. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  230. package/package/components/raw_apps/RawAppYamlEditor.svelte +81 -0
  231. package/package/components/raw_apps/RawAppYamlEditor.svelte.d.ts +20 -0
  232. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  233. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  234. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  235. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  236. package/package/components/raw_apps/datatableUtils.svelte.js +1 -1
  237. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  238. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  239. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  240. package/package/components/resources/resourceTypesFilter.js +21 -0
  241. package/package/components/restartFromStepPath.d.ts +39 -0
  242. package/package/components/restartFromStepPath.js +89 -0
  243. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  244. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  245. package/package/components/runs/JobDetailHeader.svelte +24 -3
  246. package/package/components/runs/runsFilter.d.ts +1 -1
  247. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  248. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  249. package/package/components/script_builder.d.ts +1 -1
  250. package/package/components/search/GlobalSearchModal.svelte +8 -1
  251. package/package/components/select/Select.svelte +3 -2
  252. package/package/components/select/Select.svelte.d.ts +1 -0
  253. package/package/components/settings/CreateToken.svelte +91 -71
  254. package/package/components/settings/CreateToken.svelte.d.ts +3 -0
  255. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  256. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  257. package/package/components/settings/ScopesPicker.svelte +43 -0
  258. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  259. package/package/components/settings/TokensTable.svelte +51 -15
  260. package/package/components/settings/WorkspaceUserSettings.svelte +34 -28
  261. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  262. package/package/components/sidebar/SidebarContent.svelte +68 -2
  263. package/package/components/sidebar/WorkspaceMenu.svelte +8 -4
  264. package/package/components/triggers/AddTriggersButton.svelte +17 -0
  265. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  266. package/package/components/triggers/PermissionedAsLine.svelte +37 -3
  267. package/package/components/triggers/PermissionedAsLine.svelte.d.ts +6 -0
  268. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  269. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  270. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  271. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  272. package/package/components/triggers/TriggersEditor.svelte +10 -2
  273. package/package/components/triggers/TriggersWrapper.svelte +20 -0
  274. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  275. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  276. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  277. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  278. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  279. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  280. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  281. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  282. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  283. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  284. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  285. package/package/components/triggers/azure/utils.js +56 -0
  286. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +15 -11
  287. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +22 -14
  288. package/package/components/triggers/http/RouteEditorConfigSection.svelte +15 -7
  289. package/package/components/triggers/http/RouteEditorInner.svelte +16 -14
  290. package/package/components/triggers/http/RoutesGenerator.svelte +6 -1
  291. package/package/components/triggers/http/RoutesPanel.svelte +1 -1
  292. package/package/components/triggers/http/utils.d.ts +1 -1
  293. package/package/components/triggers/http/utils.js +2 -2
  294. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +22 -14
  295. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +22 -14
  296. package/package/components/triggers/native/NativeTriggerEditor.svelte +3 -0
  297. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte +118 -0
  298. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte.d.ts +17 -0
  299. package/package/components/triggers/native/utils.js +14 -0
  300. package/package/components/triggers/nats/NatsTriggerEditor.svelte.d.ts +4 -3
  301. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +22 -14
  302. package/package/components/triggers/postgres/PostgresTriggerEditor.svelte.d.ts +4 -3
  303. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +22 -14
  304. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +22 -14
  305. package/package/components/triggers/sqs/SqsTriggerEditor.svelte.d.ts +4 -3
  306. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +22 -14
  307. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  308. package/package/components/triggers/triggers.svelte.js +24 -1
  309. package/package/components/triggers/utils.js +47 -6
  310. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +22 -14
  311. package/package/components/triggers.d.ts +1 -1
  312. package/package/components/useFolderDefaultPermissionedAs.svelte.d.ts +13 -0
  313. package/package/components/useFolderDefaultPermissionedAs.svelte.js +63 -0
  314. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  315. package/package/components/useNestedRestartState.svelte.js +320 -0
  316. package/package/components/workspaceSettings/CreateWorkspace.svelte +16 -677
  317. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte +604 -0
  318. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte.d.ts +7 -0
  319. package/package/components/workspaceSettings/CustomInstanceDbSelect.svelte +27 -25
  320. package/package/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +46 -8
  321. package/package/components/workspaceSettings/DataTableSettings.svelte +27 -22
  322. package/package/components/workspaceSettings/DucklakeSettings.svelte +1 -1
  323. package/package/components/workspaceSettings/ForkDatatableSection.svelte +228 -0
  324. package/package/components/workspaceSettings/ForkDatatableSection.svelte.d.ts +28 -0
  325. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +8 -2
  326. package/package/components/workspaceSettings/RulesetEditor.svelte +27 -2
  327. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  328. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  329. package/package/components/workspaceSettings/VolumeStorageSettings.svelte +1 -1
  330. package/package/components/workspaceSettings/WorkspaceIntegrations.svelte +17 -1
  331. package/package/consts.d.ts +3 -0
  332. package/package/consts.js +10 -0
  333. package/package/gen/core/OpenAPI.js +1 -1
  334. package/package/gen/schemas.gen.d.ts +795 -59
  335. package/package/gen/schemas.gen.js +801 -60
  336. package/package/gen/services.gen.d.ts +475 -5
  337. package/package/gen/services.gen.js +976 -23
  338. package/package/gen/types.gen.d.ts +1865 -75
  339. package/package/githubApp.js +5 -1
  340. package/package/hubPaths.json +2 -8
  341. package/package/infer.d.ts +1 -1
  342. package/package/infer.js +50 -52
  343. package/package/infer.svelte.js +10 -1
  344. package/package/mcpEndpointTools.js +60 -4
  345. package/package/monaco_workers/sqlTypePlugin.worker.d.ts +10 -0
  346. package/package/monaco_workers/sqlTypePlugin.worker.js +39 -0
  347. package/package/script_helpers.d.ts +8 -2
  348. package/package/script_helpers.js +31 -0
  349. package/package/stores.d.ts +11 -0
  350. package/package/stores.js +6 -0
  351. package/package/system_prompts/index.d.ts +1 -0
  352. package/package/system_prompts/index.js +8 -0
  353. package/package/system_prompts/prompts.d.ts +17 -13
  354. package/package/system_prompts/prompts.js +921 -61
  355. package/package/templates/ci_test_bun.ts.template +27 -0
  356. package/package/templates/ci_test_python.py.template +26 -0
  357. package/package/utils/forkConflict.d.ts +26 -0
  358. package/package/utils/forkConflict.js +56 -0
  359. package/package/utils_deployable.d.ts +164 -121
  360. package/package/utils_deployable.js +61 -11
  361. package/package/utils_workspace_deploy.d.ts +8 -8
  362. package/package/utils_workspace_deploy.js +89 -421
  363. package/package.json +30 -6
  364. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  365. package/dist/sharedUtils/base.d.ts +0 -1
  366. package/dist/sharedUtils/cloud.d.ts +0 -1
  367. package/dist/sharedUtils/common.d.ts +0 -111
  368. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  369. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  370. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  371. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  372. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  373. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  374. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  375. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  376. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  377. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  378. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  379. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  380. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  381. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  382. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  383. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  384. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  385. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  386. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  387. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  388. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  389. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  390. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  391. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  392. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  393. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  394. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  395. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  396. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  397. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  398. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  399. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  400. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  401. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  402. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  403. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  404. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  405. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  406. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  407. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  408. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  409. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  410. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  411. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  412. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  413. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  414. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  415. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  416. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  417. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  418. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  419. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  420. package/dist/sharedUtils/gen/index.d.ts +0 -6
  421. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  422. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  423. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  424. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  425. package/dist/sharedUtils/hub.d.ts +0 -49
  426. package/dist/sharedUtils/jsr.json +0 -6
  427. package/dist/sharedUtils/lib.d.ts +0 -5
  428. package/dist/sharedUtils/lib.es.js +0 -1588
  429. package/dist/sharedUtils/package.json +0 -12
  430. package/dist/sharedUtils/schema.d.ts +0 -3
  431. package/dist/sharedUtils/stores.d.ts +0 -97
  432. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  433. package/dist/sharedUtils/toast.d.ts +0 -8
  434. package/dist/sharedUtils/utils.d.ts +0 -265
  435. package/package/components/copilot/chat/__tests__/app/appChat.eval.test.js +0 -153
  436. package/package/components/copilot/chat/__tests__/app/appEvalComparison.d.ts +0 -21
  437. package/package/components/copilot/chat/__tests__/app/appEvalComparison.js +0 -136
  438. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.d.ts +0 -15
  439. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.js +0 -107
  440. package/package/components/copilot/chat/__tests__/app/appEvalRunner.d.ts +0 -50
  441. package/package/components/copilot/chat/__tests__/app/appEvalRunner.js +0 -93
  442. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.d.ts +0 -29
  443. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.js +0 -134
  444. package/package/components/copilot/chat/__tests__/app/appResultsWriter.d.ts +0 -30
  445. package/package/components/copilot/chat/__tests__/app/appResultsWriter.js +0 -197
  446. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.d.ts +0 -10
  447. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.js +0 -9
  448. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/meta.json +0 -4
  449. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.d.ts +0 -6
  450. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.js +0 -5
  451. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/meta.json +0 -4
  452. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.d.ts +0 -12
  453. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.js +0 -14
  454. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/meta.json +0 -4
  455. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.d.ts +0 -8
  456. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.js +0 -25
  457. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/meta.json +0 -4
  458. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.d.ts +0 -7
  459. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.js +0 -5
  460. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/meta.json +0 -4
  461. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.d.ts +0 -8
  462. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.js +0 -5
  463. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/meta.json +0 -4
  464. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.d.ts +0 -10
  465. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.tsx +0 -26
  466. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.d.ts +0 -10
  467. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.tsx +0 -79
  468. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.d.ts +0 -10
  469. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.tsx +0 -46
  470. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.d.ts +0 -10
  471. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.tsx +0 -56
  472. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.d.ts +0 -6
  473. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.tsx +0 -59
  474. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.d.ts +0 -16
  475. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.tsx +0 -119
  476. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.d.ts +0 -15
  477. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.js +0 -14
  478. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/meta.json +0 -4
  479. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.d.ts +0 -14
  480. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.js +0 -5
  481. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/meta.json +0 -4
  482. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.d.ts +0 -6
  483. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.js +0 -41
  484. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/meta.json +0 -4
  485. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.d.ts +0 -15
  486. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.js +0 -3
  487. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/meta.json +0 -4
  488. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.d.ts +0 -9
  489. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.tsx +0 -51
  490. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.d.ts +0 -8
  491. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.tsx +0 -27
  492. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.d.ts +0 -8
  493. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.tsx +0 -18
  494. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.d.ts +0 -12
  495. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.tsx +0 -81
  496. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.d.ts +0 -3
  497. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.js +0 -3
  498. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/meta.json +0 -4
  499. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.d.ts +0 -3
  500. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.js +0 -3
  501. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/meta.json +0 -4
  502. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.d.ts +0 -2
  503. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.tsx +0 -38
  504. package/package/components/copilot/chat/__tests__/app/variants/baseline.d.ts +0 -6
  505. package/package/components/copilot/chat/__tests__/app/variants/baseline.js +0 -10
  506. package/package/components/copilot/chat/__tests__/app/variants/index.d.ts +0 -3
  507. package/package/components/copilot/chat/__tests__/app/variants/index.js +0 -3
  508. package/package/components/copilot/chat/__tests__/app/variants/streamlined.d.ts +0 -6
  509. package/package/components/copilot/chat/__tests__/app/variants/streamlined.js +0 -137
  510. package/package/components/copilot/chat/__tests__/flow/expected/test1.json +0 -134
  511. package/package/components/copilot/chat/__tests__/flow/expected/test2.json +0 -183
  512. package/package/components/copilot/chat/__tests__/flow/expected/test3.json +0 -204
  513. package/package/components/copilot/chat/__tests__/flow/expected/test4.json +0 -175
  514. package/package/components/copilot/chat/__tests__/flow/expected/test5_modify_simple.json +0 -68
  515. package/package/components/copilot/chat/__tests__/flow/expected/test6_modify_medium.json +0 -142
  516. package/package/components/copilot/chat/__tests__/flow/expected/test7_modify_complex.json +0 -136
  517. package/package/components/copilot/chat/__tests__/flow/flowChat.eval.test.js +0 -294
  518. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.d.ts +0 -17
  519. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.js +0 -49
  520. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.d.ts +0 -12
  521. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.js +0 -79
  522. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.d.ts +0 -50
  523. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.js +0 -102
  524. package/package/components/copilot/chat/__tests__/flow/initial/test5_initial.json +0 -53
  525. package/package/components/copilot/chat/__tests__/flow/initial/test6_initial.json +0 -68
  526. package/package/components/copilot/chat/__tests__/flow/initial/test7_initial.json +0 -120
  527. package/package/components/copilot/chat/__tests__/flow/variants/baseline.d.ts +0 -6
  528. package/package/components/copilot/chat/__tests__/flow/variants/baseline.js +0 -10
  529. package/package/components/copilot/chat/__tests__/flow/variants/index.d.ts +0 -3
  530. package/package/components/copilot/chat/__tests__/flow/variants/index.js +0 -3
  531. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.d.ts +0 -15
  532. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.js +0 -388
  533. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.d.ts +0 -45
  534. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.js +0 -121
  535. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.d.ts +0 -28
  536. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.js +0 -96
  537. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.d.ts +0 -32
  538. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.js +0 -130
  539. package/package/components/copilot/chat/__tests__/shared/baseVariants.d.ts +0 -45
  540. package/package/components/copilot/chat/__tests__/shared/baseVariants.js +0 -57
  541. package/package/components/copilot/chat/__tests__/shared/index.d.ts +0 -10
  542. package/package/components/copilot/chat/__tests__/shared/index.js +0 -5
  543. package/package/components/copilot/chat/__tests__/shared/types.d.ts +0 -105
  544. package/package/components/copilot/chat/__tests__/shared/types.js +0 -9
  545. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  546. package/package/components/copilot/chat/flow/utils.d.ts +0 -14
  547. package/package/components/copilot/chat/flow/utils.js +0 -108
  548. package/package/components/flows/agentToolUtils.test.js +0 -55
  549. /package/package/components/copilot/chat/{__tests__/app/appChat.eval.test.d.ts → app/core.test.d.ts} +0 -0
  550. /package/package/components/copilot/chat/{__tests__/flow/flowChat.eval.test.d.ts → flow/helperUtils.test.d.ts} +0 -0
  551. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
  552. /package/package/components/{flows/agentToolUtils.test.d.ts → copilot/chat/flow/utils.test.d.ts} +0 -0
@@ -1,24 +1,28 @@
1
- <script lang="ts">import { AlertTriangle, ArrowDown, ArrowDownRight, ArrowRight, ArrowUp, ArrowUpRight, Building, DiffIcon, FileJson, GitFork, Loader2, Trash2, Upload } from 'lucide-svelte';
1
+ <script lang="ts">import { AlertTriangle, ArrowDown, ArrowDownRight, ArrowRight, ArrowUp, ArrowUpRight, Building, CircleCheck, CircleX, DiffIcon, FileJson, FlaskConical, GitFork, Loader2, UserPlus } from 'lucide-svelte';
2
2
  import { Alert, Badge } from './common';
3
- import { AppService, EmailTriggerService, FlowService, FolderService, GcpTriggerService, HttpTriggerService, KafkaTriggerService, MqttTriggerService, NatsTriggerService, PostgresTriggerService, ScheduleService, ScriptService, SqsTriggerService, UserService, WebsocketTriggerService, WorkspaceService } from '../gen';
3
+ import { AppService, EmailTriggerService, FlowService, FolderService, AzureTriggerService, GcpTriggerService, HttpTriggerService, KafkaTriggerService, MqttTriggerService, NatsTriggerService, PostgresTriggerService, ScheduleService, ScriptService, SqsTriggerService, UserService, WebsocketTriggerService, WorkspaceService } from '../gen';
4
4
  import Button from './common/button/Button.svelte';
5
- import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte';
6
- import Row from './common/table/Row.svelte';
7
5
  import DiffDrawer from './DiffDrawer.svelte';
8
- import DeployWorkspaceDrawer from './DeployWorkspaceDrawer.svelte';
6
+ import DiffEditor from './DiffEditor.svelte';
7
+ import Drawer from './common/drawer/Drawer.svelte';
8
+ import DrawerContent from './common/drawer/DrawerContent.svelte';
9
9
  import ParentWorkspaceProtectionAlert from './ParentWorkspaceProtectionAlert.svelte';
10
10
  import { userWorkspaces, workspaceStore } from '../stores';
11
- import { deployItem, getItemValue, getOnBehalfOf } from '../utils_workspace_deploy';
11
+ import { deployItem, deleteItemInWorkspace, getItemValue, getOnBehalfOf } from '../utils_workspace_deploy';
12
12
  import Tooltip from './Tooltip.svelte';
13
13
  import OnBehalfOfSelector, { needsOnBehalfOfSelection } from './OnBehalfOfSelector.svelte';
14
14
  import { sendUserToast } from '../toast';
15
15
  import { deepEqual } from 'fast-equals';
16
+ import { orderedJsonStringify, orderedYamlStringify } from '../utils';
16
17
  import WorkspaceDeployLayout from './WorkspaceDeployLayout.svelte';
18
+ import DeploymentRequestPanel from './deploymentRequest/DeploymentRequestPanel.svelte';
19
+ import { userStore } from '../stores';
17
20
  import { triggerDisplayNamesMap, triggerKindToTriggerType } from './triggers/utils';
18
21
  import { getEmailAddress, getEmailDomain } from './triggers/email/utils';
19
22
  import { base } from '../base';
20
23
  import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte';
21
24
  import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte';
25
+ import DatatableSchemaDiff from './DatatableSchemaDiff.svelte';
22
26
  let { currentWorkspaceId, parentWorkspaceId, comparison } = $props();
23
27
  let currentWorkspaceInfo = $derived($userWorkspaces.find((w) => w.id == currentWorkspaceId));
24
28
  let parentWorkspaceInfo = $derived($userWorkspaces.find((w) => w.id == parentWorkspaceId));
@@ -177,7 +181,10 @@ async function showDiff(kind, path) {
177
181
  });
178
182
  }
179
183
  }
180
- let allSelected = $derived(selectedItems.length == selectableDiffs.length);
184
+ // All *diff* items selected. Trigger items are opt-in and don't count
185
+ // toward "all selected" — see item merge below in deployableItems.
186
+ let allSelected = $derived(selectableDiffs.length > 0 &&
187
+ selectableDiffs.every((d) => selectedItems.includes(getItemKey(d))));
181
188
  async function selectAll() {
182
189
  selectedItems = selectableDiffs
183
190
  .map((d) => getItemKey(d))
@@ -196,21 +203,45 @@ const deploymentStatus = $state({});
196
203
  function getWorkspacedKey(workspace, key) {
197
204
  return `${workspace}/${key}`;
198
205
  }
199
- async function deploy(kind, path, workspaceToDeployTo, workspaceFrom, statusPath) {
200
- deploymentStatus[statusPath] = { status: 'loading' };
201
- const result = await deployItem({
202
- kind,
203
- path,
204
- workspaceFrom,
205
- workspaceTo: workspaceToDeployTo,
206
- onBehalfOf: getOnBehalfOfForDeploy(statusPath, kind)
207
- });
206
+ async function deploy(kind, path, workspaceToDeployTo, workspaceFrom, statusKey, trigger) {
207
+ deploymentStatus[statusKey] = { status: 'loading' };
208
+ // Check if the item was deleted in the source workspace.
209
+ // If so, archive/delete it in the target workspace instead of copying.
210
+ const diff = comparison?.diffs.find((d) => getItemKey(d) === statusKey);
211
+ const itemDeletedInSource = diff
212
+ ? mergeIntoParent
213
+ ? diff.exists_in_fork === false
214
+ : diff.exists_in_source === false
215
+ : false;
216
+ let result;
217
+ if (itemDeletedInSource) {
218
+ result = await deleteItemInWorkspace(kind, path, workspaceToDeployTo);
219
+ }
220
+ else if (trigger) {
221
+ result = await deployItem({
222
+ kind: 'trigger',
223
+ path,
224
+ workspaceFrom,
225
+ workspaceTo: workspaceToDeployTo,
226
+ additionalInformation: { triggers: { kind: trigger.triggerKind } },
227
+ onBehalfOf: getOnBehalfOfForDeploy(statusKey, 'trigger')
228
+ });
229
+ }
230
+ else {
231
+ result = await deployItem({
232
+ kind,
233
+ path,
234
+ workspaceFrom,
235
+ workspaceTo: workspaceToDeployTo,
236
+ onBehalfOf: getOnBehalfOfForDeploy(statusKey, kind)
237
+ });
238
+ }
208
239
  if (result.success) {
209
- deploymentStatus[statusPath] = { status: 'deployed' };
240
+ deploymentStatus[statusKey] = { status: 'deployed' };
210
241
  }
211
242
  else {
212
- deploymentStatus[statusPath] = { status: 'failed', error: result.error };
213
- sendUserToast(`Failed to deploy ${statusPath}: ${result.error}`);
243
+ deploymentStatus[statusKey] = { status: 'failed', error: result.error };
244
+ sendUserToast(`Failed to deploy ${statusKey}: ${result.error}`);
214
245
  }
215
246
  }
216
247
  let deploymentErrorMessage = $state('');
@@ -254,24 +285,43 @@ async function deployChanges() {
254
285
  return 1;
255
286
  return 0;
256
287
  });
288
+ let anyFailed = false;
257
289
  for (const itemKey of sortedItems) {
258
- const diff = selectableDiffs.find((d) => itemKey == getItemKey(d));
259
- if (!diff) {
290
+ const deployable = deployableItems.find((d) => d.key === itemKey);
291
+ if (!deployable) {
260
292
  sendUserToast(`Undeployable item: ${itemKey}`, true);
261
293
  continue;
262
294
  }
263
- if (mergeIntoParent) {
264
- await deploy(diff.kind, diff.path, parent, current, itemKey);
265
- }
266
- else {
267
- await deploy(diff.kind, diff.path, current, parent, itemKey);
295
+ const to = mergeIntoParent ? parent : current;
296
+ const from = mergeIntoParent ? current : parent;
297
+ await deploy(deployable.kind, deployable.path, to, from, itemKey, deployable.trigger);
298
+ if (deploymentStatus[itemKey]?.status === 'failed') {
299
+ anyFailed = true;
268
300
  }
269
301
  }
270
302
  deploying = false;
271
303
  deselectAll();
304
+ // If every selected item deployed cleanly and the direction was
305
+ // merge-into-parent, close any open deployment request for this fork.
306
+ if (!anyFailed && mergeIntoParent) {
307
+ try {
308
+ const open = await WorkspaceService.getOpenDeploymentRequest({
309
+ workspace: currentWorkspaceId
310
+ });
311
+ if (open) {
312
+ await WorkspaceService.closeDeploymentRequestMerged({
313
+ workspace: currentWorkspaceId,
314
+ id: open.id
315
+ });
316
+ deploymentRequestPanel?.refresh();
317
+ }
318
+ }
319
+ catch (e) {
320
+ console.error('Failed to close open deployment request after merge', e);
321
+ }
322
+ }
272
323
  }
273
- function toggleItem(diff) {
274
- const key = getItemKey(diff);
324
+ function toggleKey(key) {
275
325
  if (selectedItems.includes(key)) {
276
326
  selectedItems = selectedItems.filter((i) => i !== key);
277
327
  }
@@ -336,154 +386,301 @@ $effect(() => {
336
386
  [selectedItems, mergeIntoParent];
337
387
  allowBehindChangesOverride = false;
338
388
  });
339
- // Transform diffs to deployable item format for the shared layout
340
- let deployableItems = $derived((comparison?.diffs ?? [])
341
- .filter((diff) => {
342
- const key = getItemKey(diff);
343
- const isSelectable = selectableDiffs.includes(diff);
344
- const isDeployedAndIrrelevant = deploymentStatus[key]?.status === 'deployed' && !isSelectable;
345
- return !isDeployedAndIrrelevant;
346
- })
347
- .map((diff) => ({
348
- key: getItemKey(diff),
349
- path: diff.path,
350
- kind: diff.kind,
351
- diff
352
- })));
389
+ function getTriggerKey(trigger) {
390
+ return `trigger:${trigger.triggerKind}:${trigger.path}`;
391
+ }
392
+ // Transform diffs + fork triggers to deployable item format for the
393
+ // shared layout. Triggers render as inline rows alongside diff items;
394
+ // they carry no ahead/behind info and are selectable à la carte.
395
+ let deployableItems = $derived.by(() => {
396
+ const diffItems = (comparison?.diffs ?? [])
397
+ .filter((diff) => {
398
+ const key = getItemKey(diff);
399
+ const isSelectable = selectableDiffs.includes(diff);
400
+ const isDeployedAndIrrelevant = deploymentStatus[key]?.status === 'deployed' && !isSelectable;
401
+ return !isDeployedAndIrrelevant;
402
+ })
403
+ .map((diff) => ({
404
+ key: getItemKey(diff),
405
+ path: diff.path,
406
+ kind: diff.kind,
407
+ diff,
408
+ trigger: undefined
409
+ }));
410
+ const triggerItems = forkTriggers
411
+ .filter((t) => {
412
+ if (!isTriggerRelevantForDirection(t, mergeIntoParent))
413
+ return false;
414
+ const key = getTriggerKey(t);
415
+ return deploymentStatus[key]?.status !== 'deployed';
416
+ })
417
+ .map((trigger) => ({
418
+ key: getTriggerKey(trigger),
419
+ path: trigger.path,
420
+ kind: 'trigger',
421
+ triggerKind: trigger.triggerKind,
422
+ diff: undefined,
423
+ trigger
424
+ }));
425
+ return [...diffItems, ...triggerItems];
426
+ });
427
+ let ciTestResults = $state({});
428
+ async function fetchCiTests() {
429
+ if (!comparison?.diffs || !currentWorkspaceId)
430
+ return;
431
+ const items = comparison.diffs
432
+ .filter((d) => d.kind === 'script' || d.kind === 'flow' || d.kind === 'resource')
433
+ .map((d) => ({ path: d.path, kind: d.kind }));
434
+ if (items.length === 0)
435
+ return;
436
+ try {
437
+ ciTestResults = await ScriptService.getCiTestResultsBatch({
438
+ workspace: currentWorkspaceId,
439
+ requestBody: { items }
440
+ });
441
+ }
442
+ catch (e) {
443
+ console.error('Failed to fetch CI test results:', e);
444
+ }
445
+ }
446
+ $effect(() => {
447
+ if (comparison && comparison.diffs.length > 0) {
448
+ fetchCiTests();
449
+ }
450
+ });
451
+ function getCiTestStatus(diff) {
452
+ const key = `${diff.kind}:${diff.path}`;
453
+ const results = ciTestResults[key];
454
+ if (!results || results.length === 0)
455
+ return null;
456
+ if (results.some((r) => r.status === 'failure' || r.status === 'canceled'))
457
+ return 'fail';
458
+ if (results.some((r) => r.status === 'running' || (r.job_id && !r.status)))
459
+ return 'running';
460
+ if (results.every((r) => r.status === 'success'))
461
+ return 'pass';
462
+ return null;
463
+ }
464
+ // Deduplicated list of all CI tests across all items
465
+ let allCiTests = $derived.by(() => {
466
+ const seen = new Map();
467
+ for (const results of Object.values(ciTestResults)) {
468
+ for (const r of results) {
469
+ const existing = seen.get(r.test_script_path);
470
+ if (!existing ||
471
+ (r.started_at && (!existing.started_at || r.started_at > existing.started_at))) {
472
+ seen.set(r.test_script_path, r);
473
+ }
474
+ }
475
+ }
476
+ return [...seen.values()];
477
+ });
353
478
  let forkTriggers = $state([]);
354
- let loadingTriggers = $state(true);
355
- let deploymentDrawer = $state(undefined);
356
- let triggerToDelete = $state(undefined);
357
- /** Deployable trigger kinds and their list+delete services */
479
+ let deploymentRequestPanel = $state(undefined);
480
+ let hasOpenDeploymentRequest = $state(false);
481
+ /** Deployable trigger kinds and their list services */
358
482
  const triggerServices = {
359
483
  schedules: {
360
484
  list: (ws) => ScheduleService.listSchedules({ workspace: ws }),
361
- delete: (ws, path) => ScheduleService.deleteSchedule({ workspace: ws, path }),
362
485
  normalize: (item) => ({
363
486
  path: item.path,
364
487
  triggerKind: 'schedules',
365
488
  scriptPath: item.script_path,
366
489
  isFlow: item.is_flow,
367
- enabled: item.enabled,
368
- extraLabel: item.schedule
490
+ extraLabel: item.schedule,
491
+ raw: item
369
492
  })
370
493
  },
371
494
  routes: {
372
495
  list: (ws) => HttpTriggerService.listHttpTriggers({ workspace: ws }),
373
- delete: (ws, path) => HttpTriggerService.deleteHttpTrigger({ workspace: ws, path }),
374
496
  normalize: (item) => ({
375
497
  path: item.path,
376
498
  triggerKind: 'routes',
377
499
  scriptPath: item.script_path,
378
500
  isFlow: item.is_flow,
379
- enabled: item.mode === 'enabled',
380
501
  extraLabel: `${(item.http_method ?? 'get').toUpperCase()} ${item.route_path ?? ''}`
381
502
  })
382
503
  },
383
504
  websockets: {
384
505
  list: (ws) => WebsocketTriggerService.listWebsocketTriggers({ workspace: ws }),
385
- delete: (ws, path) => WebsocketTriggerService.deleteWebsocketTrigger({ workspace: ws, path }),
386
506
  normalize: (item) => ({
387
507
  path: item.path,
388
508
  triggerKind: 'websockets',
389
509
  scriptPath: item.script_path,
390
510
  isFlow: item.is_flow,
391
- enabled: item.mode === 'enabled',
392
- extraLabel: item.url
511
+ extraLabel: item.url,
512
+ raw: item
393
513
  })
394
514
  },
395
515
  kafka: {
396
516
  list: (ws) => KafkaTriggerService.listKafkaTriggers({ workspace: ws }),
397
- delete: (ws, path) => KafkaTriggerService.deleteKafkaTrigger({ workspace: ws, path }),
398
517
  normalize: (item) => ({
399
518
  path: item.path,
400
519
  triggerKind: 'kafka',
401
520
  scriptPath: item.script_path,
402
521
  isFlow: item.is_flow,
403
- enabled: item.mode === 'enabled',
404
- extraLabel: item.topics?.join(', ')
522
+ extraLabel: item.topics?.join(', '),
523
+ raw: item
405
524
  })
406
525
  },
407
526
  postgres: {
408
527
  list: (ws) => PostgresTriggerService.listPostgresTriggers({ workspace: ws }),
409
- delete: (ws, path) => PostgresTriggerService.deletePostgresTrigger({ workspace: ws, path }),
410
528
  normalize: (item) => ({
411
529
  path: item.path,
412
530
  triggerKind: 'postgres',
413
531
  scriptPath: item.script_path,
414
532
  isFlow: item.is_flow,
415
- enabled: item.mode === 'enabled'
533
+ raw: item
416
534
  })
417
535
  },
418
536
  nats: {
419
537
  list: (ws) => NatsTriggerService.listNatsTriggers({ workspace: ws }),
420
- delete: (ws, path) => NatsTriggerService.deleteNatsTrigger({ workspace: ws, path }),
421
538
  normalize: (item) => ({
422
539
  path: item.path,
423
540
  triggerKind: 'nats',
424
541
  scriptPath: item.script_path,
425
542
  isFlow: item.is_flow,
426
- enabled: item.mode === 'enabled',
427
- extraLabel: item.subjects?.join(', ')
543
+ extraLabel: item.subjects?.join(', '),
544
+ raw: item
428
545
  })
429
546
  },
430
547
  mqtt: {
431
548
  list: (ws) => MqttTriggerService.listMqttTriggers({ workspace: ws }),
432
- delete: (ws, path) => MqttTriggerService.deleteMqttTrigger({ workspace: ws, path }),
433
549
  normalize: (item) => ({
434
550
  path: item.path,
435
551
  triggerKind: 'mqtt',
436
552
  scriptPath: item.script_path,
437
553
  isFlow: item.is_flow,
438
- enabled: item.mode === 'enabled'
554
+ raw: item
439
555
  })
440
556
  },
441
557
  sqs: {
442
558
  list: (ws) => SqsTriggerService.listSqsTriggers({ workspace: ws }),
443
- delete: (ws, path) => SqsTriggerService.deleteSqsTrigger({ workspace: ws, path }),
444
559
  normalize: (item) => ({
445
560
  path: item.path,
446
561
  triggerKind: 'sqs',
447
562
  scriptPath: item.script_path,
448
563
  isFlow: item.is_flow,
449
- enabled: item.mode === 'enabled',
450
- extraLabel: item.queue_url
564
+ extraLabel: item.queue_url,
565
+ raw: item
451
566
  })
452
567
  },
453
568
  gcp: {
454
569
  list: (ws) => GcpTriggerService.listGcpTriggers({ workspace: ws }),
455
- delete: (ws, path) => GcpTriggerService.deleteGcpTrigger({ workspace: ws, path }),
456
570
  normalize: (item) => ({
457
571
  path: item.path,
458
572
  triggerKind: 'gcp',
459
573
  scriptPath: item.script_path,
460
574
  isFlow: item.is_flow,
461
- enabled: item.mode === 'enabled',
462
- extraLabel: item.topic_id
575
+ extraLabel: item.topic_id,
576
+ raw: item
577
+ })
578
+ },
579
+ azure: {
580
+ list: (ws) => AzureTriggerService.listAzureTriggers({ workspace: ws }),
581
+ normalize: (item) => ({
582
+ path: item.path,
583
+ triggerKind: 'azure',
584
+ scriptPath: item.script_path,
585
+ isFlow: item.is_flow,
586
+ extraLabel: item.topic_name ?? item.scope_resource_id,
587
+ raw: item
463
588
  })
464
589
  },
465
590
  emails: {
466
591
  list: (ws) => EmailTriggerService.listEmailTriggers({ workspace: ws }),
467
- delete: (ws, path) => EmailTriggerService.deleteEmailTrigger({ workspace: ws, path }),
468
592
  normalize: (item) => ({
469
593
  path: item.path,
470
594
  triggerKind: 'emails',
471
595
  scriptPath: item.script_path,
472
596
  isFlow: item.is_flow,
473
- enabled: item.mode === 'enabled',
474
- extraLabel: getEmailAddress(item.local_part, item.workspaced_local_part, currentWorkspaceId, emailDomain ?? '')
597
+ extraLabel: getEmailAddress(item.local_part, item.workspaced_local_part, currentWorkspaceId, emailDomain ?? ''),
598
+ raw: item
475
599
  })
476
600
  }
477
601
  };
478
602
  let emailDomain = $state(undefined);
603
+ /**
604
+ * Fields that should not count as a "change" between the parent and the
605
+ * fork. Mode/enabled are forced to 'disabled'/false on clone and stripped
606
+ * by the fork-export filter; the rest are runtime state or per-row
607
+ * metadata that always diverges. Comparing without these matches the
608
+ * semantics of "is this trigger configured the same way?" rather than
609
+ * "are these two rows byte-identical?".
610
+ */
611
+ const TRIGGER_COMPARE_IGNORE = new Set([
612
+ 'workspace_id',
613
+ 'mode',
614
+ 'enabled',
615
+ 'edited_at',
616
+ 'edited_by',
617
+ 'last_server_ping',
618
+ 'server_id',
619
+ 'error',
620
+ 'extra_perms',
621
+ 'permissioned_as'
622
+ ]);
623
+ function stripIgnoredFields(row) {
624
+ if (!row || typeof row !== 'object')
625
+ return row;
626
+ const out = {};
627
+ for (const [k, v] of Object.entries(row)) {
628
+ if (!TRIGGER_COMPARE_IGNORE.has(k))
629
+ out[k] = v;
630
+ }
631
+ return out;
632
+ }
633
+ function rowsHaveSameConfig(a, b) {
634
+ return (orderedJsonStringify(stripIgnoredFields(a)) === orderedJsonStringify(stripIgnoredFields(b)));
635
+ }
479
636
  async function fetchAllTriggers() {
480
- loadingTriggers = true;
481
637
  try {
482
638
  emailDomain = await getEmailDomain();
483
- const entries = Object.values(triggerServices);
484
- const results = await Promise.allSettled(entries.map(async (svc) => {
485
- const items = await svc.list(currentWorkspaceId);
486
- return items.map(svc.normalize);
639
+ const entries = Object.entries(triggerServices);
640
+ // Fetch fork + parent in parallel for each kind. Either side may
641
+ // fail (e.g. permission denied on parent) — fall back to empty.
642
+ const results = await Promise.allSettled(entries.map(async ([kind, svc]) => {
643
+ const [forkItems, parentItems] = await Promise.all([
644
+ svc.list(currentWorkspaceId).catch(() => []),
645
+ svc.list(parentWorkspaceId).catch(() => [])
646
+ ]);
647
+ const byPath = new Map();
648
+ for (const item of forkItems) {
649
+ byPath.set(item.path, { fork: item });
650
+ }
651
+ for (const item of parentItems) {
652
+ const entry = byPath.get(item.path) ?? {};
653
+ entry.parent = item;
654
+ byPath.set(item.path, entry);
655
+ }
656
+ const merged = [];
657
+ for (const [path, entry] of byPath) {
658
+ const sourceItem = entry.fork ?? entry.parent;
659
+ const normalized = svc.normalize(sourceItem);
660
+ let changeKind;
661
+ let hasChanges = false;
662
+ if (entry.fork && !entry.parent) {
663
+ changeKind = 'new';
664
+ }
665
+ else if (!entry.fork && entry.parent) {
666
+ changeKind = 'deleted-in-source';
667
+ }
668
+ else if (entry.fork && entry.parent) {
669
+ hasChanges = !rowsHaveSameConfig(entry.fork, entry.parent);
670
+ if (hasChanges)
671
+ changeKind = 'modified';
672
+ }
673
+ merged.push({
674
+ ...normalized,
675
+ raw: sourceItem,
676
+ hasChanges,
677
+ changeKind,
678
+ sourceRaw: entry.fork,
679
+ targetRaw: entry.parent,
680
+ path
681
+ });
682
+ }
683
+ return merged;
487
684
  }));
488
685
  forkTriggers = results.flatMap((r) => (r.status === 'fulfilled' ? r.value : []));
489
686
  }
@@ -491,52 +688,48 @@ async function fetchAllTriggers() {
491
688
  console.error('Failed to fetch fork triggers:', e);
492
689
  forkTriggers = [];
493
690
  }
494
- finally {
495
- loadingTriggers = false;
496
- }
497
691
  }
498
- function deleteTrigger(trigger) {
499
- triggerToDelete = trigger;
500
- }
501
- async function confirmDeleteTrigger() {
502
- const trigger = triggerToDelete;
503
- if (!trigger)
504
- return;
505
- triggerToDelete = undefined;
506
- const triggerType = triggerKindToTriggerType(trigger.triggerKind);
507
- const displayName = triggerType ? triggerDisplayNamesMap[triggerType] : trigger.triggerKind;
508
- try {
509
- const svc = triggerServices[trigger.triggerKind];
510
- if (!svc) {
511
- throw new Error(`No service for trigger kind: ${trigger.triggerKind}`);
512
- }
513
- await svc.delete(currentWorkspaceId, trigger.path);
514
- forkTriggers = forkTriggers.filter((t) => !(t.path === trigger.path && t.triggerKind === trigger.triggerKind));
515
- sendUserToast(`Deleted ${displayName} trigger '${trigger.path}'`);
692
+ /**
693
+ * Triggers worth showing in the merge UI given the current direction.
694
+ * - "Deploy to parent": rows that exist in fork and either don't exist in
695
+ * parent or have config differences.
696
+ * - "Update current" (pull from parent): mirror.
697
+ * Triggers that exist on both sides with identical config are filtered
698
+ * out — they would generate a no-op deploy and only add noise.
699
+ */
700
+ function isTriggerRelevantForDirection(t, deployingToParent) {
701
+ const existsInFork = !!t.sourceRaw;
702
+ const existsInParent = !!t.targetRaw;
703
+ if (deployingToParent) {
704
+ return existsInFork && (!existsInParent || !!t.hasChanges);
516
705
  }
517
- catch (e) {
518
- sendUserToast(`Failed to delete trigger '${trigger.path}': ${e.body || e.message}`, true);
706
+ else {
707
+ return existsInParent && (!existsInFork || !!t.hasChanges);
519
708
  }
520
709
  }
521
710
  function getTriggerDisplayName(triggerKind) {
522
711
  const triggerType = triggerKindToTriggerType(triggerKind);
523
712
  return triggerType ? triggerDisplayNamesMap[triggerType] : triggerKind;
524
713
  }
525
- const triggerKindToPagePath = {
526
- schedules: '/schedules',
527
- routes: '/routes',
528
- websockets: '/websocket_triggers',
529
- kafka: '/kafka_triggers',
530
- postgres: '/postgres_triggers',
531
- nats: '/nats_triggers',
532
- mqtt: '/mqtt_triggers',
533
- sqs: '/sqs_triggers',
534
- gcp: '/gcp_triggers',
535
- emails: '/email_triggers'
536
- };
537
- function getTriggerHref(triggerKind) {
538
- const pagePath = triggerKindToPagePath[triggerKind];
539
- return pagePath ? `${base}${pagePath}` : undefined;
714
+ let triggerDiffOpen = $state(false);
715
+ let triggerDiffPayload = $state(undefined);
716
+ function openTriggerDiff(t) {
717
+ // `sourceRaw` is the fork row, `targetRaw` is the parent row regardless
718
+ // of direction (set in fetchAllTriggers). The diff reads from the
719
+ // destination (left) to the source (right), matching the deploy arrow.
720
+ const sourceWorkspace = mergeIntoParent ? currentWorkspaceId : parentWorkspaceId;
721
+ const targetWorkspace = mergeIntoParent ? parentWorkspaceId : currentWorkspaceId;
722
+ const fromRow = mergeIntoParent ? t.sourceRaw : t.targetRaw;
723
+ const toRow = mergeIntoParent ? t.targetRaw : t.sourceRaw;
724
+ triggerDiffPayload = {
725
+ kindLabel: getTriggerDisplayName(t.triggerKind),
726
+ path: t.path,
727
+ originalLabel: `${targetWorkspace} (target)`,
728
+ modifiedLabel: `${sourceWorkspace} (source)`,
729
+ original: orderedYamlStringify(stripIgnoredFields(toRow ?? {})),
730
+ modified: orderedYamlStringify(stripIgnoredFields(fromRow ?? {}))
731
+ };
732
+ triggerDiffOpen = true;
540
733
  }
541
734
  // Fetch triggers when workspace is available
542
735
  $effect(() => {
@@ -561,398 +754,462 @@ $effect(() => {
561
754
  {@const selectedConflicts = conflictingDiffs.filter((e) =>
562
755
  selectedItems.includes(getItemKey(e))
563
756
  ).length}
757
+ <div class="flex flex-col gap-4">
758
+ <div class="bg-surface-tertiary p-4 rounded-md border">
759
+ <WorkspaceDeployLayout
760
+ items={deployableItems}
761
+ {selectedItems}
762
+ {deploymentStatus}
763
+ selectablePredicate={(item) =>
764
+ item.trigger != null || selectableDiffs.some((d) => getItemKey(d) === item.key)}
765
+ {allSelected}
766
+ onToggleItem={(item) => toggleKey(item.key)}
767
+ onSelectAll={selectAll}
768
+ onDeselectAll={deselectAll}
769
+ emptyMessage="No comparison data available"
770
+ >
771
+ {#snippet header()}
772
+ <div class="flex items-center justify-between bg-surface-tertiary">
773
+ <div class="flex flex-col gap-2 w-full pb-4 border-b">
774
+ <div class="flex flex-wrap gap-1 items-center">
775
+ <ToggleButtonGroup
776
+ disabled={deploying}
777
+ selected="deploy_to"
778
+ onSelected={toggleDeploymentDirection}
779
+ noWFull
780
+ >
781
+ {#snippet children({ item })}
782
+ <ToggleButton
783
+ value="deploy_to"
784
+ label="Deploy to {parentWorkspaceId}"
785
+ icon={ArrowUp}
786
+ {item}
787
+ />
788
+ <ToggleButton value="update" label="Update current" icon={ArrowDown} {item} />
789
+ {/snippet}
790
+ </ToggleButtonGroup>
791
+ {#if currentWorkspaceInfo && parentWorkspaceInfo}
792
+ <div class="flex-1 flex gap-1 items-center">
793
+ <Badge
794
+ color="transparent"
795
+ class="ml-5 font-semibold"
796
+ title={mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
797
+ >
798
+ <span class="text-secondary">merge:</span>
799
+ {#if mergeIntoParent}
800
+ <GitFork size={14} />
801
+ <span class="text-emphasis">{currentWorkspaceInfo.id}</span>
802
+ {:else}
803
+ <Building size={14} />
804
+ <span class="text-emphasis">{parentWorkspaceInfo.id}</span>
805
+ {/if}
806
+ </Badge>
807
+ <ArrowRight size={16} />
808
+ <Badge
809
+ color="transparent"
810
+ class="font-semibold"
811
+ title={!mergeIntoParent
812
+ ? currentWorkspaceInfo.name
813
+ : parentWorkspaceInfo.name}
814
+ >
815
+ <span class="text-secondary">into:</span>
816
+ {#if !mergeIntoParent}
817
+ <GitFork size={14} />
818
+ <span class="text-emphasis">{currentWorkspaceInfo.id}</span>
819
+ {:else}
820
+ <Building size={14} />
821
+ <span class="text-emphasis">{parentWorkspaceInfo.id}</span>
822
+ {/if}
823
+ </Badge>
824
+ </div>
825
+ {/if}
826
+ <div class="flex items-center gap-2 text-sm">
827
+ <Badge color="transparent">
828
+ {comparison.summary.total_diffs} total items
829
+ </Badge>
830
+ <Badge color="transparent">
831
+ {selectableDiffs.length}
832
+ {mergeIntoParent ? 'deployable' : 'updateable'}
833
+ </Badge>
834
+ {#if conflictingDiffs.length > 0}
835
+ <Badge color="orange">
836
+ <AlertTriangle class="w-3 h-3 inline mr-1" />
837
+ {conflictingDiffs.length} conflicts
838
+ </Badge>
839
+ {/if}
840
+ </div>
841
+ </div>
842
+ </div>
843
+ </div>
844
+ {/snippet}
845
+ {#if allCiTests.length > 0}
846
+ <div class="flex flex-col gap-1.5 mt-3 p-3 border bg-surface-secondary rounded text-xs">
847
+ <div class="flex items-center gap-1.5 font-semibold text-secondary">
848
+ <FlaskConical size={14} />
849
+ CI tests
850
+ </div>
851
+ <div class="flex flex-col gap-1">
852
+ {#each allCiTests as test (test.test_script_path)}
853
+ <div class="flex items-center gap-2">
854
+ {#if test.status === 'success'}
855
+ <CircleCheck size={14} class="text-green-600" />
856
+ {:else if test.status === 'failure' || test.status === 'canceled'}
857
+ <CircleX size={14} class="text-red-600" />
858
+ {:else if test.status === 'running'}
859
+ <Loader2 size={14} class="text-yellow-600 animate-spin" />
860
+ {:else}
861
+ <div class="w-3.5 h-3.5 rounded-full border border-tertiary"></div>
862
+ {/if}
863
+ <span class="text-secondary">{test.test_script_path}</span>
864
+ {#if test.job_id}
865
+ <a
866
+ href="{base}/run/{test.job_id}?workspace={currentWorkspaceId}"
867
+ class="text-tertiary hover:text-secondary text-2xs"
868
+ >
869
+ view run
870
+ </a>
871
+ {/if}
872
+ </div>
873
+ {/each}
874
+ </div>
875
+ </div>
876
+ {/if}
564
877
 
565
- <WorkspaceDeployLayout
566
- items={deployableItems}
567
- {selectedItems}
568
- {deploymentStatus}
569
- selectablePredicate={(item) => selectableDiffs.some((d) => getItemKey(d) === item.key)}
570
- {allSelected}
571
- onToggleItem={(item) => {
572
- const diff = comparison?.diffs.find((d) => getItemKey(d) === item.key)
573
- if (diff) toggleItem(diff)
574
- }}
575
- onSelectAll={selectAll}
576
- onDeselectAll={deselectAll}
577
- emptyMessage="No comparison data available"
578
- >
579
- {#snippet header()}
580
- <div class="flex items-center justify-between">
581
- <div
582
- class="flex flex-col gap-2 border bg-surface-tertiary w-full p-4 border-radius-5 rounded"
583
- >
584
- <div class="flex flex-row gap-1 items-center">
585
- <ToggleButtonGroup
586
- disabled={deploying}
587
- selected="deploy_to"
588
- onSelected={toggleDeploymentDirection}
589
- noWFull
878
+ {#snippet alerts()}
879
+ {#if mergeIntoParent}
880
+ <ParentWorkspaceProtectionAlert
881
+ {parentWorkspaceId}
882
+ onUpdateCanDeploy={(canDeploy) => {
883
+ canDeployToParent = canDeploy
884
+ }}
885
+ />
886
+ {/if}
887
+ {#if conflictingDiffs.length > 0}
888
+ <Alert title="Conflicting changes detected" type="warning" class="mt-2">
889
+ <span>
890
+ {conflictingDiffs.length} item{conflictingDiffs.length !== 1 ? 's have' : ' has'} conflicting
891
+ changes, it was modified on the original workspace while changes were made on this fork.
892
+ Make sure to resolve these before merging.
893
+ </span>
894
+ </Alert>
895
+ {/if}
896
+ {#if hasBehindChanges && hasAheadChanges && !(mergeIntoParent && !canDeployToParent)}
897
+ <Alert
898
+ title="This fork is behind {parentWorkspaceId} and needs to be up to date before deploying"
899
+ type="warning"
900
+ class="my-2"
590
901
  >
591
- {#snippet children({ item })}
592
- <ToggleButton
593
- value="deploy_to"
594
- label="Deploy to {parentWorkspaceId}"
595
- icon={ArrowUp}
596
- {item}
902
+ You have items behind '{parentWorkspaceId}'. You need to update and test your changes
903
+ before being able to deploy.
904
+ <span class="font-medium flex flex-row gap-1 text-red-500">
905
+ <input
906
+ type="checkbox"
907
+ bind:checked={allowBehindChangesOverride}
908
+ class="rounded max-w-4"
597
909
  />
598
- <ToggleButton value="update" label="Update current" icon={ArrowDown} {item} />
599
- {/snippet}
600
- </ToggleButtonGroup>
601
- {#if currentWorkspaceInfo && parentWorkspaceInfo}
910
+ Override: Deploy despite {itemsWithBehindChanges.length} outdated item{itemsWithBehindChanges.length !==
911
+ 1
912
+ ? 's'
913
+ : ''}
914
+ </span>
915
+ </Alert>
916
+ {/if}
917
+ {#if !comparison.all_ahead_items_visible || !comparison.all_behind_items_visible}
918
+ <Alert
919
+ title="This fork has changes not visible to your user"
920
+ type="warning"
921
+ class="my-2"
922
+ >
923
+ {#if !comparison.all_ahead_items_visible && !comparison.all_behind_items_visible}
924
+ This fork is ahead and behind its parent
925
+ {:else if !comparison.all_behind_items_visible}
926
+ This fork is behind of its parent
927
+ {:else if !comparison.all_ahead_items_visible}
928
+ This fork is ahead of its parent
929
+ {/if}
930
+ and some of the changes are not visible by you. Only a user with access to the whole context
931
+ may deploy or update this fork. You can share the link to this page to someone with proper
932
+ permissions to get it deployed.
933
+ </Alert>
934
+ {/if}
935
+ {/snippet}
936
+
937
+ {#snippet itemSummary(item)}
938
+ {#if item.trigger}
939
+ {@const t = item.trigger as ForkTrigger}
940
+ <span class="text-emphasis">{getTriggerDisplayName(t.triggerKind)}</span>
941
+ {#if t.extraLabel}
942
+ <span class="text-secondary ml-1">{t.extraLabel}</span>
943
+ {/if}
944
+ <span class="text-tertiary mx-1">&rarr;</span>
945
+ <span class="text-secondary">{t.scriptPath}</span>
946
+ {:else}
947
+ {@const diff = item.diff as WorkspaceItemDiff}
948
+ {@const key = item.key}
949
+ {@const isSelectable = selectableDiffs.includes(diff)}
950
+ {@const oldSummary = mergeIntoParent
951
+ ? summaryCache[key]?.parent
952
+ : summaryCache[key]?.current}
953
+ {@const newSummary = mergeIntoParent
954
+ ? summaryCache[key]?.current
955
+ : summaryCache[key]?.parent}
956
+ {@const existsInBothWorkspaces = !(
957
+ (diff.exists_in_fork && !diff.exists_in_source) ||
958
+ (!diff.exists_in_fork && diff.exists_in_source)
959
+ )}
960
+ {#if oldSummary != newSummary && isSelectable && existsInBothWorkspaces}
961
+ <span class="line-through text-secondary">{oldSummary || diff.path}</span>
962
+ {newSummary || diff.path}
963
+ {:else if !existsInBothWorkspaces}
964
+ {newSummary || oldSummary || diff.path}
965
+ {:else}
966
+ {newSummary || diff.path}
967
+ {/if}
968
+ {/if}
969
+ {/snippet}
970
+
971
+ {#snippet itemActions(item)}
972
+ {#if item.trigger}
973
+ {@const t = item.trigger as ForkTrigger}
974
+ {@const key = item.key}
975
+ {#if t.changeKind === 'new'}
602
976
  <Badge
603
- color="transparent"
604
- class="ml-5 font-semibold"
605
- title={mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
977
+ title={mergeIntoParent
978
+ ? `Only exists in '${currentWorkspaceId}'`
979
+ : `Only exists in '${parentWorkspaceId}'`}
980
+ color="indigo"
981
+ size="xs">New</Badge
606
982
  >
607
- <span class="text-secondary">merge:</span>
608
- {#if mergeIntoParent}
609
- <GitFork size={14} />
610
- <span class="text-emphasis">{currentWorkspaceInfo.id}</span>
611
- {:else}
612
- <Building size={14} />
613
- <span class="text-emphasis">{parentWorkspaceInfo.id}</span>
614
- {/if}
615
- </Badge>
616
- <ArrowRight size={16} />
983
+ {/if}
984
+ {#if t.isFlow}
985
+ <Badge color="blue" size="xs">flow</Badge>
986
+ {/if}
987
+ {#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
988
+ {#if mergeIntoParent}
989
+ <Badge color="green" size="xs">
990
+ <ArrowUpRight class="w-3 h-3 inline" />
991
+ 1 ahead
992
+ </Badge>
993
+ {:else}
994
+ <Badge color="blue" size="xs">
995
+ <ArrowDownRight class="w-3 h-3 inline" />
996
+ 1 behind
997
+ </Badge>
998
+ {/if}
999
+ {#if t.changeKind === 'modified'}
1000
+ <div>
1001
+ <Button size="xs" variant="subtle" onclick={() => openTriggerDiff(t)}>
1002
+ <DiffIcon class="w-3 h-3" />
1003
+ Show diff
1004
+ </Button>
1005
+ </div>
1006
+ {/if}
1007
+ {/if}
1008
+ {:else}
1009
+ {@const diff = item.diff as WorkspaceItemDiff}
1010
+ {@const key = item.key}
1011
+ {@const targetOnBehalfOf = getTargetOnBehalfOf(key)}
1012
+ {@const isConflict = diff.ahead > 0 && diff.behind > 0}
1013
+ {@const existsInBothWorkspaces = !(
1014
+ (diff.exists_in_fork && !diff.exists_in_source) ||
1015
+ (!diff.exists_in_fork && diff.exists_in_source)
1016
+ )}
1017
+ <!-- On-behalf-of selector -->
1018
+ {#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
1019
+ <OnBehalfOfSelector
1020
+ targetWorkspace={deployTargetWorkspace}
1021
+ targetValue={targetOnBehalfOf}
1022
+ selected={onBehalfOfChoice[key]}
1023
+ onSelect={(choice, details) => {
1024
+ onBehalfOfChoice[key] = choice
1025
+ if (details) customOnBehalfOf[key] = details
1026
+ }}
1027
+ kind={diff.kind}
1028
+ canPreserve={canPreserveOnBehalfOf}
1029
+ customValue={customOnBehalfOf[key]?.permissionedAs}
1030
+ />
1031
+ {/if}
1032
+ {#if diff.kind === 'raw_app'}
1033
+ <Badge small icon={{ icon: FileJson }}>Raw</Badge>
1034
+ {/if}
1035
+ <!-- Status badges -->
1036
+ {#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
617
1037
  <Badge
618
- color="transparent"
619
- class="font-semibold"
620
- title={!mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
1038
+ title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
1039
+ color="indigo"
1040
+ size="xs">New</Badge
621
1041
  >
622
- <span class="text-secondary">into:</span>
623
- {#if !mergeIntoParent}
624
- <GitFork size={14} />
625
- <span class="text-emphasis">{currentWorkspaceInfo.id}</span>
626
- {:else}
627
- <Building size={14} />
628
- <span class="text-emphasis">{parentWorkspaceInfo.id}</span>
629
- {/if}
630
- </Badge>
631
1042
  {/if}
632
- </div>
633
- <div class="flex items-center gap-2 text-sm">
634
- <Badge color="transparent">
635
- {comparison.summary.total_diffs} total items
636
- </Badge>
637
- <Badge color="transparent">
638
- {selectableDiffs.length}
639
- {mergeIntoParent ? 'deployable' : 'updateable'}
640
- </Badge>
641
- {#if conflictingDiffs.length > 0}
642
- <Badge color="orange">
643
- <AlertTriangle class="w-3 h-3 inline mr-1" />
644
- {conflictingDiffs.length} conflicts
645
- </Badge>
1043
+ {#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
1044
+ <Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
1045
+ >Deleted</Badge
1046
+ >
646
1047
  {/if}
647
- </div>
648
- </div>
649
- </div>
650
- {/snippet}
651
-
652
- {#snippet alerts()}
653
- {#if mergeIntoParent}
654
- <ParentWorkspaceProtectionAlert
655
- {parentWorkspaceId}
656
- onUpdateCanDeploy={(canDeploy) => {
657
- canDeployToParent = canDeploy
658
- }}
659
- />
660
- {/if}
661
- {#if conflictingDiffs.length > 0}
662
- <Alert title="Conflicting changes detected" type="warning" class="mt-2">
663
- <span>
664
- {conflictingDiffs.length} item{conflictingDiffs.length !== 1 ? 's have' : ' has'} conflicting
665
- changes, it was modified on the original workspace while changes were made on this fork.
666
- Make sure to resolve these before merging.
667
- </span>
668
- </Alert>
669
- {/if}
670
- {#if hasBehindChanges && hasAheadChanges && !(mergeIntoParent && !canDeployToParent)}
671
- <Alert
672
- title="This fork is behind {parentWorkspaceId} and needs to be up to date before deploying"
673
- type="warning"
674
- class="my-2"
675
- >
676
- You have items behind '{parentWorkspaceId}'. You need to update and test your changes
677
- before being able to deploy.
678
- <span class="font-medium flex flex-row gap-1 text-red-500">
679
- <input
680
- type="checkbox"
681
- bind:checked={allowBehindChangesOverride}
682
- class="rounded max-w-4"
683
- />
684
- Override: Deploy despite {itemsWithBehindChanges.length} outdated item{itemsWithBehindChanges.length !==
685
- 1
686
- ? 's'
687
- : ''}
688
- </span>
689
- </Alert>
690
- {/if}
691
- {#if !comparison.all_ahead_items_visible || !comparison.all_behind_items_visible}
692
- <Alert title="This fork has changes not visible to your user" type="warning" class="my-2">
693
- {#if !comparison.all_ahead_items_visible && !comparison.all_behind_items_visible}
694
- This fork is ahead and behind its parent
695
- {:else if !comparison.all_behind_items_visible}
696
- This fork is behind of its parent
697
- {:else if !comparison.all_ahead_items_visible}
698
- This fork is ahead of its parent
699
- {/if}
700
- and some of the changes are not visible by you. Only a user with access to the whole context
701
- may deploy or update this fork. You can share the link to this page to someone with proper
702
- permissions to get it deployed.
703
- </Alert>
704
- {/if}
705
- {/snippet}
706
-
707
- {#snippet itemSummary(item)}
708
- {@const diff = item.diff as WorkspaceItemDiff}
709
- {@const key = item.key}
710
- {@const isSelectable = selectableDiffs.includes(diff)}
711
- {@const oldSummary = mergeIntoParent ? summaryCache[key]?.parent : summaryCache[key]?.current}
712
- {@const newSummary = mergeIntoParent ? summaryCache[key]?.current : summaryCache[key]?.parent}
713
- {@const existsInBothWorkspaces = !(
714
- (diff.exists_in_fork && !diff.exists_in_source) ||
715
- (!diff.exists_in_fork && diff.exists_in_source)
716
- )}
717
- {#if oldSummary != newSummary && isSelectable && existsInBothWorkspaces}
718
- <span class="line-through text-secondary">{oldSummary || diff.path}</span>
719
- {newSummary || diff.path}
720
- {:else if !existsInBothWorkspaces}
721
- {newSummary || oldSummary || diff.path}
722
- {:else}
723
- {newSummary || diff.path}
724
- {/if}
725
- {/snippet}
726
-
727
- {#snippet itemActions(item)}
728
- {@const diff = item.diff as WorkspaceItemDiff}
729
- {@const key = item.key}
730
- {@const targetOnBehalfOf = getTargetOnBehalfOf(key)}
731
- {@const isConflict = diff.ahead > 0 && diff.behind > 0}
732
- {@const existsInBothWorkspaces = !(
733
- (diff.exists_in_fork && !diff.exists_in_source) ||
734
- (!diff.exists_in_fork && diff.exists_in_source)
735
- )}
736
- <!-- On-behalf-of selector -->
737
- {#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
738
- <OnBehalfOfSelector
739
- targetWorkspace={deployTargetWorkspace}
740
- targetValue={targetOnBehalfOf}
741
- selected={onBehalfOfChoice[key]}
742
- onSelect={(choice, details) => {
743
- onBehalfOfChoice[key] = choice
744
- if (details) customOnBehalfOf[key] = details
745
- }}
746
- kind={diff.kind}
747
- canPreserve={canPreserveOnBehalfOf}
748
- customValue={customOnBehalfOf[key]?.permissionedAs}
749
- />
750
- {/if}
751
- {#if diff.kind === 'raw_app'}
752
- <Badge small icon={{ icon: FileJson }}>Raw</Badge>
753
- {/if}
754
- <!-- Status badges -->
755
- {#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
756
- <Badge
757
- title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
758
- color="indigo"
759
- size="xs">New</Badge
760
- >
761
- {/if}
762
- {#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
763
- <Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
764
- >Deleted</Badge
765
- >
766
- {/if}
767
- {#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
768
- <Badge
769
- title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
770
- color="red"
771
- size="xs">Deleted</Badge
772
- >
773
- {/if}
774
- {#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
775
- <Badge
776
- title="This item was newly created in '{currentWorkspaceId}'"
777
- color="indigo"
778
- size="xs">New</Badge
779
- >
780
- {/if}
781
- {#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
782
- <div class="flex items-center gap-2">
783
- {#if isConflict || existsInBothWorkspaces}
784
- {#if diff.ahead > 0}
785
- <Badge color="green" size="xs">
786
- <ArrowUpRight class="w-3 h-3 inline" />
787
- {diff.ahead} ahead
788
- </Badge>
1048
+ {#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
1049
+ <Badge
1050
+ title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
1051
+ color="red"
1052
+ size="xs">Deleted</Badge
1053
+ >
1054
+ {/if}
1055
+ {#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
1056
+ <Badge
1057
+ title="This item was newly created in '{currentWorkspaceId}'"
1058
+ color="indigo"
1059
+ size="xs">New</Badge
1060
+ >
789
1061
  {/if}
790
- {#if diff.behind > 0}
791
- <Badge color="blue" size="xs">
792
- <ArrowDownRight class="w-3 h-3 inline" />
793
- {diff.behind} behind
794
- </Badge>
1062
+ {@const ciStatus = getCiTestStatus(diff)}
1063
+ {#if ciStatus === 'pass'}
1064
+ <Badge color="green" size="xs"><CircleCheck size={10} class="mr-0.5" />CI pass</Badge>
1065
+ {:else if ciStatus === 'fail'}
1066
+ <Badge color="red" size="xs"><CircleX size={10} class="mr-0.5" />CI fail</Badge>
1067
+ {:else if ciStatus === 'running'}
1068
+ <Badge color="yellow" size="xs"
1069
+ ><Loader2 size={10} class="mr-0.5 animate-spin" />CI</Badge
1070
+ >
795
1071
  {/if}
796
- {#if isConflict}
797
- <Badge color="orange" size="xs">
798
- <AlertTriangle class="w-3 h-3 inline" />
799
- Conflict
800
- </Badge>
1072
+ {#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
1073
+ <div class="flex items-center gap-2">
1074
+ {#if isConflict || existsInBothWorkspaces}
1075
+ {#if diff.ahead > 0}
1076
+ <Badge color="green" size="xs">
1077
+ <ArrowUpRight class="w-3 h-3 inline" />
1078
+ {diff.ahead} ahead
1079
+ </Badge>
1080
+ {/if}
1081
+ {#if diff.behind > 0}
1082
+ <Badge color="blue" size="xs">
1083
+ <ArrowDownRight class="w-3 h-3 inline" />
1084
+ {diff.behind} behind
1085
+ </Badge>
1086
+ {/if}
1087
+ {#if isConflict}
1088
+ <Badge color="orange" size="xs">
1089
+ <AlertTriangle class="w-3 h-3 inline" />
1090
+ Conflict
1091
+ </Badge>
1092
+ {/if}
1093
+ {/if}
1094
+ </div>
1095
+ <div class:invisible={!existsInBothWorkspaces}>
1096
+ <Button
1097
+ size="xs"
1098
+ variant="subtle"
1099
+ onclick={() => showDiff(diff.kind as Kind, diff.path)}
1100
+ >
1101
+ <DiffIcon class="w-3 h-3" />
1102
+ Show diff
1103
+ </Button>
1104
+ </div>
801
1105
  {/if}
802
1106
  {/if}
803
- </div>
804
- <div class:invisible={!existsInBothWorkspaces}>
805
- <Button size="xs" variant="subtle" onclick={() => showDiff(diff.kind as Kind, diff.path)}>
806
- <DiffIcon class="w-3 h-3" />
807
- Show diff
808
- </Button>
809
- </div>
810
- {/if}
811
- {/snippet}
1107
+ {/snippet}
812
1108
 
813
- {#snippet footer()}
814
- <div class="flex items-center justify-between">
815
- <div></div>
1109
+ {#snippet footer()}
1110
+ <div class="flex items-center justify-between">
1111
+ <div></div>
816
1112
 
817
- <div class="flex flex-col items-end gap-2">
818
- {#if comparison.all_behind_items_visible && comparison.all_ahead_items_visible}
819
- {#if !(mergeIntoParent && !canDeployToParent)}
820
- <Button
821
- color="blue"
822
- disabled={selectedItems.length === 0 ||
823
- deploying ||
824
- (hasBehindChanges && !allowBehindChangesOverride) ||
825
- (mergeIntoParent && !canDeployToParent) ||
826
- hasUnselectedOnBehalfOf}
827
- loading={deploying}
828
- on:click={deployChanges}
829
- >
830
- {mergeIntoParent ? 'Deploy' : 'Update'}
831
- {selectedItems.length} Item{selectedItems.length !== 1 ? 's' : ''}
832
- {#if selectedConflicts != 0}
833
- ({selectedConflicts} conflicts)
1113
+ <div class="flex flex-col items-end gap-2">
1114
+ {#if comparison.all_behind_items_visible && comparison.all_ahead_items_visible}
1115
+ <div class="flex items-center gap-2">
1116
+ {#if mergeIntoParent && !hasOpenDeploymentRequest && !deploymentRequestPanel?.isDialogOpen()}
1117
+ <Button
1118
+ variant="default"
1119
+ startIcon={{ icon: UserPlus }}
1120
+ on:click={() => deploymentRequestPanel?.openRequestDialog()}
1121
+ >
1122
+ Request deployment
1123
+ </Button>
1124
+ {/if}
1125
+ <Button
1126
+ variant="accent"
1127
+ disabled={selectedItems.length === 0 ||
1128
+ deploying ||
1129
+ (hasBehindChanges && !allowBehindChangesOverride) ||
1130
+ (mergeIntoParent && !canDeployToParent) ||
1131
+ hasUnselectedOnBehalfOf}
1132
+ loading={deploying}
1133
+ on:click={deployChanges}
1134
+ >
1135
+ {mergeIntoParent ? 'Deploy' : 'Update'}
1136
+ {selectedItems.length} Item{selectedItems.length !== 1 ? 's' : ''}
1137
+ {#if selectedConflicts != 0}
1138
+ ({selectedConflicts} conflicts)
1139
+ {/if}
1140
+ </Button>
1141
+ </div>
1142
+ {#if !(mergeIntoParent && !canDeployToParent) && hasUnselectedOnBehalfOf}
1143
+ <span class="text-xs text-yellow-600">
1144
+ You must set the "on behalf of" user for all items before deploying
1145
+ <Tooltip class="text-yellow-600">
1146
+ The "run on behalf of" field defines which user's permissions will be applied
1147
+ during execution. Make sure this is set to an appropriate user before
1148
+ deploying.
1149
+ </Tooltip>
1150
+ </span>
834
1151
  {/if}
835
- </Button>
836
- {#if hasUnselectedOnBehalfOf}
837
- <span class="text-xs text-yellow-600">
838
- You must set the "on behalf of" user for all items before deploying
839
- <Tooltip class="text-yellow-600">
840
- The "run on behalf of" field defines which user's permissions will be applied
841
- during execution. Make sure this is set to an appropriate user before deploying.
842
- </Tooltip>
843
- </span>
844
1152
  {/if}
845
- {/if}
846
- {/if}
847
1153
 
848
- {#if deploymentErrorMessage != ''}
849
- <Alert
850
- title="Cannot {mergeIntoParent ? 'deploy these changes' : 'update these items'}"
851
- type="error"
852
- class="my-2 max-w-80"
853
- >
854
- <span>
855
- {deploymentErrorMessage}
856
- </span>
857
- </Alert>
858
- {/if}
859
- </div>
860
- </div>
861
- {/snippet}
862
- </WorkspaceDeployLayout>
1154
+ {#if deploymentErrorMessage != ''}
1155
+ <Alert
1156
+ title="Cannot {mergeIntoParent ? 'deploy these changes' : 'update these items'}"
1157
+ type="error"
1158
+ class="my-2 max-w-80"
1159
+ >
1160
+ <span>
1161
+ {deploymentErrorMessage}
1162
+ </span>
1163
+ </Alert>
1164
+ {/if}
1165
+ </div>
1166
+ </div>
1167
+ {/snippet}
1168
+ </WorkspaceDeployLayout>
863
1169
 
864
- <!-- Fork Triggers Section -->
865
- <div class="mt-6">
866
- <div class="flex items-center gap-2 mb-2">
867
- <h3 class="text-sm font-semibold">Triggers created in this fork</h3>
868
- {#if !loadingTriggers}
869
- <Badge color="indigo" size="xs"
870
- >{forkTriggers.length} trigger{forkTriggers.length !== 1 ? 's' : ''}</Badge
871
- >
872
- {/if}
1170
+ <DeploymentRequestPanel
1171
+ bind:this={deploymentRequestPanel}
1172
+ forkWorkspaceId={currentWorkspaceId}
1173
+ {parentWorkspaceId}
1174
+ currentUsername={$userStore?.username ?? ''}
1175
+ isAdmin={$userStore?.is_admin ?? false}
1176
+ onStateChange={(open) => {
1177
+ hasOpenDeploymentRequest = open
1178
+ }}
1179
+ />
873
1180
  </div>
874
1181
 
875
- <Alert title="Deploy and/or delete these triggers" type="info" class="mb-2">
876
- When forking a workspace, triggers are not forked to avoid unnecessary executions or
877
- collisions. If you created this triggers with the intention of deploying them to the parent
878
- workspace, you can do so here. Otherwise it is recommended to delete them or disable them.
879
- </Alert>
880
-
881
- {#if loadingTriggers}
882
- <div class="flex items-center gap-2 text-secondary text-sm p-4">
883
- <Loader2 class="animate-spin w-4 h-4" />
884
- Loading triggers...
885
- </div>
886
- {:else if forkTriggers.length === 0}
887
- <div class="text-secondary text-sm p-4 border rounded-md bg-surface-tertiary">
888
- No triggers in this fork workspace.
889
- </div>
890
- {:else}
891
- <div class="border rounded-md bg-surface-tertiary">
892
- {#each forkTriggers as trigger (trigger.triggerKind + ':' + trigger.path)}
893
- <Row
894
- kind="trigger"
895
- triggerKind={trigger.triggerKind}
896
- path={trigger.path}
897
- href={getTriggerHref(trigger.triggerKind)}
898
- marked={undefined}
899
- isSelectable={false}
900
- canFavorite={false}
901
- workspaceId={currentWorkspaceId}
902
- >
903
- {#snippet customSummary()}
904
- <span>{getTriggerDisplayName(trigger.triggerKind)}</span>
905
- <span class="text-secondary mx-1">&rarr;</span>
906
- <span class="text-secondary">{trigger.scriptPath}</span>
907
- {#if trigger.isFlow}
908
- <Badge color="blue" size="xs">flow</Badge>
909
- {/if}
910
- {#if trigger.extraLabel}
911
- <span class="text-tertiary text-xs">({trigger.extraLabel})</span>
912
- {/if}
913
- {/snippet}
914
- {#snippet actions()}
915
- {#if trigger.enabled != null}
916
- <Badge color={trigger.enabled ? 'green' : 'gray'} size="xs">
917
- {trigger.enabled ? 'Enabled' : 'Disabled'}
918
- </Badge>
919
- {/if}
920
- <Button
921
- size="xs"
922
- variant="subtle"
923
- onclick={() => {
924
- deploymentDrawer?.openDrawer(trigger.path, 'trigger', {
925
- triggers: { kind: trigger.triggerKind }
926
- })
927
- }}
928
- >
929
- <Upload size={12} />
930
- Deploy
931
- </Button>
932
- <Button size="xs" variant="subtle" color="red" onclick={() => deleteTrigger(trigger)}>
933
- <Trash2 size={12} />
934
- </Button>
935
- {/snippet}
936
- </Row>
937
- {/each}
938
- </div>
939
- {/if}
1182
+ <div class="bg-surface-tertiary p-4 rounded-md border">
1183
+ <DatatableSchemaDiff {currentWorkspaceId} {parentWorkspaceId} />
1184
+ </div>
940
1185
  </div>
941
1186
 
942
- <DeployWorkspaceDrawer bind:this={deploymentDrawer} />
943
1187
  <DiffDrawer bind:this={diffDrawer} {isFlow} />
944
- <ConfirmationModal
945
- title="Delete trigger"
946
- confirmationText="Delete"
947
- open={!!triggerToDelete}
948
- onConfirmed={confirmDeleteTrigger}
949
- onCanceled={() => (triggerToDelete = undefined)}
950
- >
951
- {#if triggerToDelete}
952
- Are you sure you want to delete the {getTriggerDisplayName(triggerToDelete.triggerKind)} trigger
953
- '{triggerToDelete.path}'?
954
- {/if}
955
- </ConfirmationModal>
1188
+
1189
+ <Drawer bind:open={triggerDiffOpen} size="900px">
1190
+ <DrawerContent
1191
+ title={triggerDiffPayload
1192
+ ? `${triggerDiffPayload.kindLabel} ${triggerDiffPayload.path}`
1193
+ : 'Trigger diff'}
1194
+ on:close={() => (triggerDiffOpen = false)}
1195
+ >
1196
+ {#if triggerDiffPayload}
1197
+ <div class="flex flex-col h-full">
1198
+ <div class="flex-1 min-h-0">
1199
+ <DiffEditor
1200
+ open={triggerDiffOpen}
1201
+ className="!h-full"
1202
+ defaultLang="yaml"
1203
+ defaultOriginal={triggerDiffPayload.original}
1204
+ defaultModified={triggerDiffPayload.modified}
1205
+ readOnly
1206
+ inlineDiff={false}
1207
+ />
1208
+ </div>
1209
+ </div>
1210
+ {/if}
1211
+ </DrawerContent>
1212
+ </Drawer>
956
1213
  {:else}
957
1214
  <div class="flex items-center justify-center h-full">
958
1215
  <div class="text-gray-500">No comparison data available</div>