windmill-components 1.665.1 → 1.677.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +2 -0
  2. package/dist/sharedUtils/base.d.ts +1 -0
  3. package/dist/sharedUtils/cloud.d.ts +1 -0
  4. package/dist/sharedUtils/common.d.ts +111 -0
  5. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +5 -0
  6. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +5 -0
  7. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +5 -0
  8. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +13 -0
  9. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +11 -0
  10. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +95 -0
  11. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +6 -0
  12. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +7 -0
  13. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +33 -0
  14. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +10 -0
  15. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +5371 -0
  16. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +3 -0
  17. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +3 -0
  18. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +7 -0
  19. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +3 -0
  20. package/dist/sharedUtils/components/apps/gridUtils.d.ts +14 -0
  21. package/dist/sharedUtils/components/apps/inputType.d.ts +178 -0
  22. package/dist/sharedUtils/components/apps/rx.d.ts +29 -0
  23. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +21 -0
  24. package/dist/sharedUtils/components/apps/types.d.ts +274 -0
  25. package/dist/sharedUtils/components/assets/lib.d.ts +25 -0
  26. package/dist/sharedUtils/components/common/alert/model.d.ts +2 -0
  27. package/dist/sharedUtils/components/common/badge/model.d.ts +8 -0
  28. package/dist/sharedUtils/components/common/button/model.d.ts +45 -0
  29. package/dist/sharedUtils/components/common/fileInput/model.d.ts +1 -0
  30. package/dist/sharedUtils/components/common/index.d.ts +24 -0
  31. package/dist/sharedUtils/components/common/skeleton/model.d.ts +21 -0
  32. package/dist/sharedUtils/components/dbTypes.d.ts +14 -0
  33. package/dist/sharedUtils/components/diff_drawer.d.ts +26 -0
  34. package/dist/sharedUtils/components/ducklake.d.ts +1 -0
  35. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +7 -0
  36. package/dist/sharedUtils/components/icons/index.d.ts +101 -0
  37. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +1 -0
  38. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +10 -0
  39. package/dist/sharedUtils/components/raw_apps/utils.d.ts +15 -0
  40. package/dist/sharedUtils/components/triggers/email/utils.d.ts +4 -0
  41. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +2 -0
  42. package/dist/sharedUtils/components/triggers/http/utils.d.ts +11 -0
  43. package/dist/sharedUtils/components/triggers/kafka/utils.d.ts +2 -0
  44. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +2 -0
  45. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +2 -0
  46. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +8 -0
  47. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +2 -0
  48. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +32 -0
  49. package/dist/sharedUtils/components/triggers/utils.d.ts +80 -0
  50. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +2 -0
  51. package/dist/sharedUtils/components/triggers.d.ts +20 -0
  52. package/dist/sharedUtils/gen/core/ApiError.d.ts +10 -0
  53. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +13 -0
  54. package/dist/sharedUtils/gen/core/ApiResult.d.ts +7 -0
  55. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +26 -0
  56. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +27 -0
  57. package/dist/sharedUtils/gen/core/request.d.ts +29 -0
  58. package/dist/sharedUtils/gen/index.d.ts +6 -0
  59. package/dist/sharedUtils/gen/schemas.gen.d.ts +7036 -0
  60. package/dist/sharedUtils/gen/services.gen.d.ts +6047 -0
  61. package/dist/sharedUtils/gen/types.gen.d.ts +21881 -0
  62. package/dist/sharedUtils/history.svelte.d.ts +9 -0
  63. package/dist/sharedUtils/hub.d.ts +49 -0
  64. package/dist/sharedUtils/jsr.json +6 -0
  65. package/dist/sharedUtils/lib.d.ts +5 -0
  66. package/dist/sharedUtils/lib.es.js +1588 -0
  67. package/dist/sharedUtils/package.json +12 -0
  68. package/dist/sharedUtils/schema.d.ts +3 -0
  69. package/dist/sharedUtils/stores.d.ts +97 -0
  70. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +80 -0
  71. package/dist/sharedUtils/toast.d.ts +8 -0
  72. package/dist/sharedUtils/utils.d.ts +265 -0
  73. package/package/components/AddUser.svelte +67 -34
  74. package/package/components/AppConnectInner.svelte +9 -1
  75. package/package/components/ArgInfo.svelte +9 -1
  76. package/package/components/ArgInput.svelte +21 -1
  77. package/package/components/CompareWorkspaces.svelte +11 -2
  78. package/package/components/DedicatedWorkersSelector.svelte +262 -247
  79. package/package/components/DefaultTagsInner.svelte +40 -2
  80. package/package/components/DeployWorkspace.svelte +13 -0
  81. package/package/components/DiffEditor.svelte +44 -1
  82. package/package/components/EditableSchemaForm.svelte +5 -2
  83. package/package/components/EditableSchemaForm.svelte.d.ts +1 -0
  84. package/package/components/Editor.svelte +5 -1
  85. package/package/components/EditorBar.svelte +12 -3
  86. package/package/components/FilterSearchbar.svelte +26 -2
  87. package/package/components/FlowBuilder.svelte +6 -3
  88. package/package/components/FlowGraphDiffViewer.svelte +16 -17
  89. package/package/components/FlowGraphViewer.svelte +20 -6
  90. package/package/components/FlowGraphViewer.svelte.d.ts +2 -0
  91. package/package/components/FlowGraphViewerStep.svelte +14 -32
  92. package/package/components/FlowMetadata.svelte +4 -1
  93. package/package/components/FlowPreviewContent.svelte +2 -0
  94. package/package/components/FlowStatusWaitingForEvents.svelte +25 -4
  95. package/package/components/HighlightCode.svelte +3 -0
  96. package/package/components/InstanceSetting.svelte +9 -25
  97. package/package/components/InstanceSettings.svelte +16 -0
  98. package/package/components/LabelsInput.svelte +149 -0
  99. package/package/components/LabelsInput.svelte.d.ts +8 -0
  100. package/package/components/Login.svelte +6 -1
  101. package/package/components/ObjectStoreConfigSettings.svelte +273 -1
  102. package/package/components/OktaSetting.svelte +6 -5
  103. package/package/components/Password.svelte +74 -20
  104. package/package/components/Password.svelte.d.ts +1 -0
  105. package/package/components/PasswordArgInput.svelte +2 -2
  106. package/package/components/PasswordArgInput.svelte.d.ts +1 -0
  107. package/package/components/Path.svelte +8 -10
  108. package/package/components/PathNameAutocomplete.svelte +308 -0
  109. package/package/components/PathNameAutocomplete.svelte.d.ts +27 -0
  110. package/package/components/PowerShellCommonParams.svelte +84 -0
  111. package/package/components/PowerShellCommonParams.svelte.d.ts +6 -0
  112. package/package/components/Range.svelte +8 -3
  113. package/package/components/ResourceEditor.svelte +6 -2
  114. package/package/components/RunForm.svelte +71 -7
  115. package/package/components/RunForm.svelte.d.ts +2 -1
  116. package/package/components/ScriptBuilder.svelte +7 -3
  117. package/package/components/ScriptEditor.svelte +221 -187
  118. package/package/components/ScriptEditor.svelte.d.ts +1 -1
  119. package/package/components/ScriptSchema.svelte +1 -1
  120. package/package/components/StringTypeNarrowing.svelte +1 -1
  121. package/package/components/StringTypeNarrowing.svelte.d.ts +1 -1
  122. package/package/components/SummaryPathDisplay.svelte +32 -10
  123. package/package/components/SummaryPathDisplay.svelte.d.ts +2 -1
  124. package/package/components/VariableEditor.svelte +9 -2
  125. package/package/components/WorkerGroup.svelte +47 -2
  126. package/package/components/apps/editor/DeploymentHistory.svelte +112 -13
  127. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +135 -35
  128. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte.d.ts +3 -1
  129. package/package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +11 -35
  130. package/package/components/apps/editor/settingsPanel/mainInput/runnableSelectorUtils.d.ts +10 -0
  131. package/package/components/apps/editor/settingsPanel/mainInput/runnableSelectorUtils.js +14 -0
  132. package/package/components/apps/editor/settingsPanel/mainInput/runnableSelectorUtils.test.d.ts +1 -0
  133. package/package/components/apps/editor/settingsPanel/mainInput/runnableSelectorUtils.test.js +34 -0
  134. package/package/components/assets/AssetButtons.svelte +21 -25
  135. package/package/components/assets/AssetsUsageDrawer.svelte +7 -9
  136. package/package/components/common/fileUpload/FileUpload.svelte +6 -2
  137. package/package/components/common/languageIcons/LanguageIcon.svelte +3 -0
  138. package/package/components/common/table/AppRow.svelte +18 -0
  139. package/package/components/common/table/FlowRow.svelte +18 -0
  140. package/package/components/common/table/ScriptRow.svelte +18 -0
  141. package/package/components/copilot/chat/AIChatManager.svelte.js +3 -3
  142. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  143. package/package/components/copilot/chat/flow/openFlowZod.js +3 -3
  144. package/package/components/custom_ui.d.ts +2 -0
  145. package/package/components/details/DetailPageHeader.svelte +2 -2
  146. package/package/components/details/DetailPageHeader.svelte.d.ts +2 -1
  147. package/package/components/flows/agentToolUtils.d.ts +5 -0
  148. package/package/components/flows/agentToolUtils.js +49 -0
  149. package/package/components/flows/agentToolUtils.test.d.ts +1 -0
  150. package/package/components/flows/agentToolUtils.test.js +55 -0
  151. package/package/components/flows/content/FlowInput.svelte +2 -0
  152. package/package/components/flows/content/FlowInputsQuick.svelte +1 -1
  153. package/package/components/flows/content/FlowLoop.svelte +5 -12
  154. package/package/components/flows/content/FlowModuleScript.svelte +5 -3
  155. package/package/components/flows/content/FlowPathViewer.svelte +2 -2
  156. package/package/components/flows/content/FlowPathViewer.svelte.d.ts +1 -0
  157. package/package/components/flows/content/FlowSettings.svelte +2 -0
  158. package/package/components/flows/content/FlowWhileLoop.svelte +5 -12
  159. package/package/components/flows/flowInfers.js +8 -3
  160. package/package/components/flows/flowStore.svelte.d.ts +1 -1
  161. package/package/components/flows/map/FlowModuleSchemaMap.svelte +49 -9
  162. package/package/components/flows/pickers/PickHubScriptQuick.svelte +5 -3
  163. package/package/components/flows/scheduleUtils.js +2 -1
  164. package/package/components/graph/FlowGraphV2.svelte +13 -1
  165. package/package/components/graph/WacDiagram.svelte +96 -0
  166. package/package/components/graph/WacDiagram.svelte.d.ts +7 -0
  167. package/package/components/graph/noteEditor.svelte.d.ts +1 -1
  168. package/package/components/graph/noteEditor.svelte.js +12 -1
  169. package/package/components/graph/noteUtils.svelte.d.ts +1 -1
  170. package/package/components/graph/noteUtils.svelte.js +9 -2
  171. package/package/components/graph/renderers/edges/WacEdge.svelte +41 -0
  172. package/package/components/graph/renderers/edges/WacEdge.svelte.d.ts +4 -0
  173. package/package/components/graph/renderers/nodes/WacControlNode.svelte +51 -0
  174. package/package/components/graph/renderers/nodes/WacControlNode.svelte.d.ts +9 -0
  175. package/package/components/graph/renderers/nodes/WacStepNode.svelte +35 -0
  176. package/package/components/graph/renderers/nodes/WacStepNode.svelte.d.ts +9 -0
  177. package/package/components/graph/wacDagLayout.d.ts +10 -0
  178. package/package/components/graph/wacDagLayout.js +120 -0
  179. package/package/components/graph/wacToFlow.js +1 -1
  180. package/package/components/home/ItemsList.svelte +28 -4
  181. package/package/components/icons/RIcon.svelte +32 -0
  182. package/package/components/icons/RIcon.svelte.d.ts +7 -0
  183. package/package/components/instanceSettings/DbHealth.svelte +723 -0
  184. package/package/components/instanceSettings/DbHealth.svelte.d.ts +3 -0
  185. package/package/components/instanceSettings/SecretBackendConfig.svelte +343 -304
  186. package/package/components/instanceSettings/SmtpSettings.svelte +8 -0
  187. package/package/components/instanceSettings.js +14 -5
  188. package/package/components/mcp/McpScopeSelector.svelte +82 -16
  189. package/package/components/moveRenameManager.d.ts +1 -0
  190. package/package/components/moveRenameManager.js +7 -4
  191. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +14 -1
  192. package/package/components/raw_apps/rawAppPolicy.js +3 -2
  193. package/package/components/raw_apps/utils.test.d.ts +1 -0
  194. package/package/components/raw_apps/utils.test.js +38 -0
  195. package/package/components/resources/resourcesFilter.d.ts +15 -2
  196. package/package/components/resources/resourcesFilter.js +11 -2
  197. package/package/components/runs/JobDetailFieldConfig.js +5 -3
  198. package/package/components/runs/JobDetailHeader.svelte +5 -2
  199. package/package/components/runs/JobRunsPreview.svelte +1 -0
  200. package/package/components/runs/RunBadges.svelte +7 -4
  201. package/package/components/runs/RunRow.svelte +7 -7
  202. package/package/components/schedules/schedulesFilter.d.ts +15 -2
  203. package/package/components/schedules/schedulesFilter.js +11 -2
  204. package/package/components/schema/EditableSchemaWrapper.svelte +6 -8
  205. package/package/components/schema/PropertyEditor.svelte +22 -1
  206. package/package/components/schema/PropertyEditor.svelte.d.ts +1 -0
  207. package/package/components/schema/editable_schema_wrapper.d.ts +1 -0
  208. package/package/components/secretArgUtils.d.ts +7 -0
  209. package/package/components/secretArgUtils.js +45 -0
  210. package/package/components/settings/WorkspaceUserSettings.svelte +359 -286
  211. package/package/components/sidebar/OperatorMenu.svelte +215 -197
  212. package/package/components/triggers/CaptureWrapper.svelte +1 -1
  213. package/package/components/triggers/TriggerFilters.svelte +17 -5
  214. package/package/components/triggers/TriggerFilters.svelte.d.ts +2 -1
  215. package/package/components/triggers/kafka/KafkaCapture.svelte +6 -2
  216. package/package/components/triggers/kafka/KafkaCapture.svelte.d.ts +1 -1
  217. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +5 -1
  218. package/package/components/triggers/kafka/utils.js +1 -0
  219. package/package/components/triggers/mqtt/MqttEditorConfigSection.svelte.d.ts +1 -1
  220. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +6 -0
  221. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +87 -1
  222. package/package/components/triggers/websocket/utils.js +2 -0
  223. package/package/components/variables/variablesFilter.d.ts +15 -2
  224. package/package/components/variables/variablesFilter.js +11 -2
  225. package/package/components/worker_group.js +1 -0
  226. package/package/components/workspaceSettings/DucklakeSettings.svelte +33 -41
  227. package/package/consts.d.ts +1 -0
  228. package/package/consts.js +1 -0
  229. package/package/editorLangUtils.d.ts +1 -1
  230. package/package/editorLangUtils.js +2 -0
  231. package/package/gen/core/OpenAPI.js +1 -1
  232. package/package/gen/schemas.gen.d.ts +346 -4
  233. package/package/gen/schemas.gen.js +347 -5
  234. package/package/gen/services.gen.d.ts +163 -1
  235. package/package/gen/services.gen.js +323 -17
  236. package/package/gen/types.gen.d.ts +671 -5
  237. package/package/hubPaths.json +6 -3
  238. package/package/infer.d.ts +55 -0
  239. package/package/infer.js +131 -0
  240. package/package/infer.svelte.js +2 -0
  241. package/package/mcpEndpointTools.js +213 -22
  242. package/package/script_helpers.d.ts +3 -0
  243. package/package/script_helpers.js +26 -0
  244. package/package/scripts.d.ts +2 -1
  245. package/package/scripts.js +15 -3
  246. package/package/stores.d.ts +2 -0
  247. package/package/system_prompts/prompts.d.ts +6 -5
  248. package/package/system_prompts/prompts.js +188 -29
  249. package/package/user.js +5 -1
  250. package/package/utils.js +21 -0
  251. package/package/utils_deployable.d.ts +11 -0
  252. package/package/utils_workspace_deploy.js +36 -8
  253. package/package.json +5 -4
@@ -1,9 +1,9 @@
1
- <script lang="ts">import { TriangleAlert, Plus, RefreshCcwIcon, RotateCcw, Settings, Trash, X, ExternalLink, FileCode } from 'lucide-svelte';
1
+ <script lang="ts">import { TriangleAlert, Plus, RefreshCcwIcon, RotateCcw, Settings, Trash, Power, X, ExternalLink, FileCode } from 'lucide-svelte';
2
2
  import { Alert, Button, Drawer } from './common';
3
3
  import Badge from './common/badge/Badge.svelte';
4
4
  import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte';
5
5
  import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte';
6
- import { ConfigService, WorkspaceService } from '../gen';
6
+ import { ConfigService, SettingService, WorkspaceService } from '../gen';
7
7
  import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte';
8
8
  import { createEventDispatcher } from 'svelte';
9
9
  import { sendUserToast } from '../toast';
@@ -155,6 +155,7 @@ let hasChanges = $derived.by(() => {
155
155
  });
156
156
  let openDelete = $state(false);
157
157
  let openClean = $state(false);
158
+ let openRestart = $state(false);
158
159
  // Compute hashed tags for display (actual tags used by the worker)
159
160
  let hashedDedicatedTags = $state(new Map());
160
161
  $effect(() => {
@@ -243,6 +244,32 @@ $effect(() => {
243
244
  </div>
244
245
  </ConfirmationModal>
245
246
 
247
+ <ConfirmationModal
248
+ open={openRestart}
249
+ title="Restart workers"
250
+ confirmationText="Restart"
251
+ on:canceled={() => {
252
+ openRestart = false
253
+ }}
254
+ on:confirmed={async () => {
255
+ try {
256
+ await SettingService.restartWorkerGroup({ workerGroup: name })
257
+ sendUserToast(`Restart signal sent to worker group '${name}'`)
258
+ dispatch('reload')
259
+ } catch (e) {
260
+ sendUserToast(`Failed to restart worker group: ${e}`, true)
261
+ }
262
+ openRestart = false
263
+ }}
264
+ >
265
+ <div class="flex flex-col w-full space-y-4">
266
+ <span
267
+ >Are you sure you want to restart all workers in worker group '{name}'? Workers will be
268
+ gracefully shut down and are expected to be restarted by their supervisor.</span
269
+ >
270
+ </div>
271
+ </ConfirmationModal>
272
+
246
273
  <Drawer bind:this={drawer} size="800px">
247
274
  <DrawerContent
248
275
  on:close={() => drawer?.closeDrawer()}
@@ -1114,6 +1141,17 @@ $effect(() => {
1114
1141
  >
1115
1142
  Clean cache
1116
1143
  </Button>
1144
+ <Button
1145
+ unifiedSize="sm"
1146
+ variant="subtle"
1147
+ on:click={() => {
1148
+ openRestart = true
1149
+ }}
1150
+ startIcon={{ icon: Power }}
1151
+ destructive
1152
+ >
1153
+ Restart workers
1154
+ </Button>
1117
1155
  {:else}
1118
1156
  <Dropdown
1119
1157
  items={[
@@ -1126,6 +1164,13 @@ $effect(() => {
1126
1164
  disabled: !config,
1127
1165
  type: 'delete'
1128
1166
  },
1167
+ {
1168
+ displayName: 'Restart workers',
1169
+ action: () => {
1170
+ openRestart = true
1171
+ },
1172
+ type: 'delete'
1173
+ },
1129
1174
  {
1130
1175
  displayName: 'Delete config',
1131
1176
  action: () => {
@@ -2,20 +2,34 @@
2
2
  const bubble = createBubbler();
3
3
  import { Pane, Splitpanes } from 'svelte-splitpanes';
4
4
  import PanelSection from './settingsPanel/common/PanelSection.svelte';
5
- import { classNames, displayDate, emptyString } from '../../../utils';
5
+ import { classNames, cleanValueProperties, displayDate, emptyString, orderedYamlStringify, replaceFalseWithUndefined } from '../../../utils';
6
6
  import { AppService } from '../../../gen';
7
7
  import { workspaceStore } from '../../../stores';
8
8
  import { Skeleton } from '../../common';
9
9
  import Button from '../../common/button/Button.svelte';
10
10
  import { createEventDispatcher, untrack } from 'svelte';
11
11
  import { Pencil, ArrowRight, X, Loader2 } from 'lucide-svelte';
12
+ import Select from '../../select/Select.svelte';
12
13
  let { appPath } = $props();
13
14
  let loading = $state(false);
14
15
  let versions = $state([]);
15
16
  let selectedVersion = $state(undefined);
16
17
  let selected = $state(undefined);
18
+ let previousVersion = $state(undefined);
19
+ let selectedVersionIndex = $state(undefined);
20
+ let previousVersionId = $state(undefined);
21
+ let versionCache = $state({});
17
22
  let deploymentMsgUpdateMode = $state(false);
18
23
  let deploymentMsgUpdate = $state(undefined);
24
+ async function getVersionApp(version) {
25
+ const cached = versionCache[version];
26
+ if (cached) {
27
+ return cached;
28
+ }
29
+ const app = await AppService.getAppByVersion({ workspace: $workspaceStore, id: version });
30
+ versionCache[version] = app;
31
+ return app;
32
+ }
19
33
  async function loadVersions() {
20
34
  if (appPath === undefined) {
21
35
  return;
@@ -27,9 +41,17 @@ async function loadVersions() {
27
41
  });
28
42
  loading = false;
29
43
  }
30
- async function loadValue(version) {
31
- let app = await AppService.getAppByVersion({ workspace: $workspaceStore, id: version });
32
- selected = app;
44
+ async function loadSelectedVersion(version) {
45
+ const app = await getVersionApp(version);
46
+ if (selectedVersion?.version === version) {
47
+ selected = app;
48
+ }
49
+ }
50
+ async function loadPreviousVersion(version) {
51
+ const app = await getVersionApp(version);
52
+ if (previousVersionId === version) {
53
+ previousVersion = app;
54
+ }
33
55
  }
34
56
  async function updateDeploymentMsg(appId, appVersion) {
35
57
  if (selectedVersion === undefined ||
@@ -50,14 +72,54 @@ async function updateDeploymentMsg(appId, appVersion) {
50
72
  deploymentMsgUpdateMode = false;
51
73
  loadVersions();
52
74
  }
75
+ function toComparableVersionValue(app) {
76
+ return app.value;
77
+ }
78
+ function toVersionLabel(version) {
79
+ return emptyString(version.deployment_msg) ? `Version ${version.version}` : version.deployment_msg;
80
+ }
81
+ let availableVersions = $derived(selectedVersionIndex !== undefined ? versions.slice(selectedVersionIndex + 1) : []);
82
+ let compareVersionItems = $derived(availableVersions.map((version) => ({
83
+ label: toVersionLabel(version),
84
+ value: version.version
85
+ })));
86
+ let selectedVersionYaml = $derived.by(() => {
87
+ if (!selected)
88
+ return undefined;
89
+ return orderedYamlStringify(replaceFalseWithUndefined(cleanValueProperties(toComparableVersionValue(selected))));
90
+ });
91
+ let previousVersionYaml = $derived.by(() => {
92
+ if (!previousVersion)
93
+ return undefined;
94
+ return orderedYamlStringify(replaceFalseWithUndefined(cleanValueProperties(toComparableVersionValue(previousVersion))));
95
+ });
53
96
  const dispatch = createEventDispatcher();
54
97
  loadVersions();
55
98
  $effect(() => {
56
99
  selectedVersion?.version !== undefined &&
57
100
  untrack(() => {
58
- selectedVersion && loadValue(selectedVersion.version);
101
+ selectedVersion && loadSelectedVersion(selectedVersion.version);
59
102
  });
60
103
  });
104
+ $effect(() => {
105
+ if (previousVersionId === undefined) {
106
+ previousVersion = undefined;
107
+ return;
108
+ }
109
+ const version = previousVersionId;
110
+ untrack(() => {
111
+ loadPreviousVersion(version);
112
+ });
113
+ });
114
+ $effect(() => {
115
+ if (availableVersions.length === 0) {
116
+ previousVersionId = undefined;
117
+ return;
118
+ }
119
+ if (!availableVersions.some((version) => version.version === previousVersionId)) {
120
+ previousVersionId = availableVersions[0]?.version;
121
+ }
122
+ });
61
123
  </script>
62
124
 
63
125
  <Splitpanes class="!overflow-visible">
@@ -67,7 +129,7 @@ $effect(() => {
67
129
  {#if !loading}
68
130
  {#if versions.length > 0}
69
131
  <div class="flex gap-2 flex-col">
70
- {#each versions ?? [] as version}
132
+ {#each versions ?? [] as version, versionIndex}
71
133
  <!-- svelte-ignore a11y_click_events_have_key_events -->
72
134
  <!-- svelte-ignore a11y_no_static_element_interactions -->
73
135
  <div
@@ -77,12 +139,14 @@ $effect(() => {
77
139
  )}
78
140
  onclick={() => {
79
141
  selectedVersion = version
142
+ selectedVersionIndex = versionIndex
143
+ previousVersionId = versions[versionIndex + 1]?.version
80
144
  deploymentMsgUpdateMode = false
81
145
  deploymentMsgUpdate = undefined
82
146
  }}
83
147
  >
84
148
  <span class="text-xs truncate">
85
- {#if emptyString(version.deployment_msg)}Version {version.version}{:else}{version.deployment_msg}{/if}
149
+ {toVersionLabel(version)}
86
150
  </span>
87
151
  </div>
88
152
  {/each}
@@ -164,7 +228,10 @@ $effect(() => {
164
228
  <div class="flex p-1 gap-2">
165
229
  <Button
166
230
  size="xs"
167
- on:click={() => window.open(`/apps/add?template_id=${selectedVersion?.version}`)}
231
+ on:click={() =>
232
+ window.open(
233
+ `${selected?.raw_app ? '/apps_raw' : '/apps'}/add?template_id=${selectedVersion?.version}`
234
+ )}
168
235
  >
169
236
  Restore as fork
170
237
  </Button>
@@ -174,11 +241,43 @@ $effect(() => {
174
241
  </div>
175
242
  </div>
176
243
 
177
- {#await import('./AppPreview.svelte')}
178
- <Loader2 class="animate-spin" />
179
- {:then Module}
180
- <Module.default noBackend app={selected.value} context={{}} />
181
- {/await}
244
+ <div class="flex flex-col gap-2">
245
+ {#if availableVersions.length > 0}
246
+ <div class="flex flex-row items-center gap-2 py-2">
247
+ <div class="text-xs">Compare with:</div>
248
+ <Select
249
+ items={compareVersionItems}
250
+ bind:value={previousVersionId}
251
+ class="w-56"
252
+ size="sm"
253
+ />
254
+ </div>
255
+
256
+ <div class="h-[calc(100vh-260px)] min-h-[420px]">
257
+ {#if previousVersionYaml && selectedVersionYaml}
258
+ {#await import('../../DiffEditor.svelte')}
259
+ <Loader2 class="animate-spin" />
260
+ {:then Module}
261
+ <Module.default
262
+ open={true}
263
+ automaticLayout
264
+ className="h-full"
265
+ defaultLang="yaml"
266
+ defaultOriginal={previousVersionYaml}
267
+ defaultModified={selectedVersionYaml}
268
+ readOnly
269
+ />
270
+ {/await}
271
+ {:else}
272
+ <Loader2 class="animate-spin" />
273
+ {/if}
274
+ </div>
275
+ {:else}
276
+ <div class="text-sm p-2 text-primary">
277
+ No older deployment is available to compare with this version.
278
+ </div>
279
+ {/if}
280
+ </div>
182
281
  {:else}
183
282
  <Skeleton layout={[[40]]} />
184
283
  {/if}
@@ -2,9 +2,11 @@
2
2
  const bubble = createBubbler();
3
3
  import { Button, Drawer, DrawerContent } from '../../../common';
4
4
  import { base } from '../../../../base';
5
+ import FlowGraphViewer from '../../../FlowGraphViewer.svelte';
6
+ import Skeleton from '../../../common/skeleton/Skeleton.svelte';
5
7
  import FlowModuleScript from '../../../flows/content/FlowModuleScript.svelte';
6
8
  import FlowPathViewer from '../../../flows/content/FlowPathViewer.svelte';
7
- import { emptySchema, sendUserToast } from '../../../../utils';
9
+ import { emptySchema, getHubFlowIdFromPath, isHubFlowPath, sendUserToast } from '../../../../utils';
8
10
  import { getContext, tick, untrack } from 'svelte';
9
11
  import { workspaceStore } from '../../../../stores';
10
12
  import { createEventDispatcher } from 'svelte';
@@ -20,18 +22,22 @@ import RunButton from '../../../RunButton.svelte';
20
22
  import Popover from '../../../meltComponents/Popover.svelte';
21
23
  import ScriptEditorDrawer from '../../../flows/content/ScriptEditorDrawer.svelte';
22
24
  import FlowEditorDrawer from '../../../flows/content/FlowEditorDrawer.svelte';
23
- import { ScriptService } from '../../../../gen';
24
- let { runnable = $bindable(), fields = $bindable(), id, rawApps = false, isLoading = false, onRun = async () => { }, onCancel = async () => { } } = $props();
25
+ import { FlowService, ScriptService } from '../../../../gen';
26
+ import { replaceScriptPlaceholderWithItsValues } from '../../../../hub';
27
+ let { runnable = $bindable(), fields = $bindable(), id, rawApps = false, isLoading = false, onRun = async () => { }, onCancel = async () => { }, hubFlowPreview = $bindable(undefined) } = $props();
25
28
  const viewerContext = getContext('AppViewerContext');
26
29
  let drawerFlowViewer = $state(undefined);
27
30
  let flowPath = $state('');
31
+ let drawerShowsHubFlow = $state(false);
28
32
  let notFound = $state(false);
33
+ let hubFlowId = $derived(getHubFlowIdFromPath(runnable.path));
29
34
  // Key to force re-mounting of viewer components (bypasses FlowModuleScript cache)
30
35
  let refreshKey = $state(0);
31
36
  let scriptEditorDrawer = $state(undefined);
32
37
  let flowEditorDrawer = $state(undefined);
33
38
  const dispatch = createEventDispatcher();
34
39
  async function refreshScript(runnable) {
40
+ hubFlowPreview = undefined;
35
41
  try {
36
42
  let { schema } = await getScriptByPath(runnable.path);
37
43
  if (!deepEqual(runnable.schema, schema)) {
@@ -48,7 +54,32 @@ async function refreshScript(runnable) {
48
54
  }
49
55
  }
50
56
  async function refreshFlow(runnable) {
57
+ hubFlowPreview = undefined;
51
58
  try {
59
+ const hubFlowId = getHubFlowIdFromPath(runnable.path);
60
+ if (hubFlowId !== undefined) {
61
+ const hub = await FlowService.getHubFlowById({ id: hubFlowId });
62
+ const flow = hub.flow ? structuredClone(hub.flow) : undefined;
63
+ if (flow?.value.preprocessor_module?.value.type === 'rawscript') {
64
+ flow.value.preprocessor_module.value.content = replaceScriptPlaceholderWithItsValues(String(hubFlowId), flow.value.preprocessor_module.value.content);
65
+ }
66
+ if (!flow) {
67
+ notFound = true;
68
+ return;
69
+ }
70
+ hubFlowPreview = flow;
71
+ const schema = flow.schema && typeof flow.schema === 'object' && Object.keys(flow.schema).length > 0
72
+ ? flow.schema
73
+ : emptySchema();
74
+ if (!deepEqual(runnable.schema, schema)) {
75
+ runnable.schema = schema;
76
+ if (!runnable.schema.order) {
77
+ runnable.schema.order = Object.keys(runnable.schema.properties ?? {});
78
+ }
79
+ fields = computeFields(schema, false, fields ?? {});
80
+ }
81
+ return;
82
+ }
52
83
  const { schema } = (await loadSchema($workspaceStore ?? '', runnable.path, 'flow')) ?? emptySchema();
53
84
  if (!deepEqual(runnable.schema, schema)) {
54
85
  runnable.schema = schema;
@@ -119,6 +150,9 @@ function refresh(runnable) {
119
150
  else if (runnable.runType == 'flow') {
120
151
  refreshFlow(runnable);
121
152
  }
153
+ else {
154
+ hubFlowPreview = undefined;
155
+ }
122
156
  lastRunnable = runnable;
123
157
  }
124
158
  $effect(() => {
@@ -130,8 +164,34 @@ $effect(() => {
130
164
  </script>
131
165
 
132
166
  <Drawer bind:this={drawerFlowViewer} size="1200px">
133
- <DrawerContent title="Flow {flowPath}" on:close={drawerFlowViewer.closeDrawer}>
134
- <FlowPathViewer path={flowPath ?? ''} />
167
+ <DrawerContent
168
+ title="Flow {flowPath}"
169
+ on:close={() => {
170
+ flowPath = ''
171
+ drawerShowsHubFlow = false
172
+ drawerFlowViewer?.closeDrawer()
173
+ }}
174
+ >
175
+ {#if drawerShowsHubFlow}
176
+ <div class="flex flex-col flex-1 h-full min-h-0 overflow-auto">
177
+ {#if hubFlowPreview}
178
+ <FlowGraphViewer
179
+ triggerNode
180
+ provideTriggerContext
181
+ fillAvailableHeight
182
+ flow={{ ...hubFlowPreview, path: flowPath }}
183
+ />
184
+ {:else if notFound}
185
+ <div class="p-4 text-red-400">Hub flow not found at {flowPath}</div>
186
+ {:else}
187
+ <div class="p-4">
188
+ <Skeleton layout={[[40]]} />
189
+ </div>
190
+ {/if}
191
+ </div>
192
+ {:else if flowPath}
193
+ <FlowPathViewer path={flowPath} fillAvailableHeight />
194
+ {/if}
135
195
  </DrawerContent>
136
196
  </Drawer>
137
197
 
@@ -170,7 +230,7 @@ $effect(() => {
170
230
  size="xs"
171
231
  startIcon={{ icon: RefreshCw }}
172
232
  on:click={async () => {
173
- sendUserToast('Getting latest script version at that path')
233
+ sendUserToast('Getting latest runnable version at that path')
174
234
  // Increment refreshKey to force re-mounting of viewer components (bypasses cache)
175
235
  refreshKey++
176
236
  lastRunnable = undefined
@@ -198,31 +258,45 @@ $effect(() => {
198
258
  startIcon={{ icon: Eye }}
199
259
  on:click={() => {
200
260
  flowPath = runnable.path
261
+ drawerShowsHubFlow = isHubFlowPath(runnable.path)
201
262
  drawerFlowViewer?.openDrawer()
202
263
  }}
203
264
  >
204
265
  Expand
205
266
  </Button>
206
- <Button
207
- variant="default"
208
- size="xs"
209
- startIcon={{ icon: Pen }}
210
- on:click={() => {
211
- openFlowEditor(runnable.path)
212
- }}
213
- >
214
- Edit
215
- </Button>
216
- <Button
217
- variant="default"
218
- size="xs"
219
- startIcon={{ icon: Eye }}
220
- endIcon={{ icon: ExternalLink }}
221
- target="_blank"
222
- href="{base}/flows/get/{runnable.path}?workspace={$workspaceStore}"
223
- >
224
- Details
225
- </Button>
267
+ {#if hubFlowId}
268
+ <Button
269
+ variant="default"
270
+ size="xs"
271
+ startIcon={{ icon: GitFork }}
272
+ endIcon={{ icon: ExternalLink }}
273
+ target="_blank"
274
+ href="{base}/flows/add?hub={hubFlowId}"
275
+ >
276
+ Fork
277
+ </Button>
278
+ {:else}
279
+ <Button
280
+ variant="default"
281
+ size="xs"
282
+ startIcon={{ icon: Pen }}
283
+ on:click={() => {
284
+ openFlowEditor(runnable.path)
285
+ }}
286
+ >
287
+ Edit
288
+ </Button>
289
+ <Button
290
+ variant="default"
291
+ size="xs"
292
+ startIcon={{ icon: Eye }}
293
+ endIcon={{ icon: ExternalLink }}
294
+ target="_blank"
295
+ href="{base}/flows/get/{runnable.path}?workspace={$workspaceStore}"
296
+ >
297
+ Details
298
+ </Button>
299
+ {/if}
226
300
  {:else}
227
301
  <Button
228
302
  size="xs"
@@ -268,13 +342,20 @@ $effect(() => {
268
342
  nonCaptureEvent={true}
269
343
  btnClasses={'bg-surface text-primay hover:bg-hover'}
270
344
  variant="default"
271
- size="xs">Cache</Button
345
+ size="xs"
272
346
  >
347
+ Cache
348
+ </Button>
273
349
  {/snippet}
274
350
  {#snippet content()}
275
- Since this is a reference to a workspace {runnable.runType}, set the cache in the {runnable.runType}
276
- settings directly by editing it. The cache will be shared by any app or flow that uses this
277
- {runnable.runType}.
351
+ {#if runnable.runType == 'flow' && isHubFlowPath(runnable.path)}
352
+ Since this is a reference to a hub flow, cache settings are managed from the flow after
353
+ you fork it into your workspace.
354
+ {:else}
355
+ Since this is a reference to a workspace {runnable.runType}, set the cache in the
356
+ {runnable.runType} settings directly by editing it. The cache will be shared by any app or
357
+ flow that uses this {runnable.runType}.
358
+ {/if}
278
359
  {/snippet}
279
360
  </Popover>
280
361
 
@@ -285,18 +366,37 @@ $effect(() => {
285
366
  class="!text-xs !rounded-xs"
286
367
  />
287
368
  </div>
288
- <div class="w-full grow overflow-y-auto">
369
+ <div class="w-full grow min-h-0 overflow-y-auto">
289
370
  {#key `${viewerContext?.stateId ? get(viewerContext.stateId) : 0}-${refreshKey}`}
290
371
  {#if notFound}
291
- <div class="text-red-400"
292
- >{runnable.runType} not found at {runnable.path} in workspace {$workspaceStore}</div
293
- >
372
+ <div class="text-red-400">
373
+ {#if runnable.runType == 'flow' && isHubFlowPath(runnable.path)}
374
+ Hub flow not found at {runnable.path}
375
+ {:else}
376
+ {runnable.runType} not found at {runnable.path} in workspace {$workspaceStore}
377
+ {/if}
378
+ </div>
294
379
  {:else if runnable.runType == 'script' || runnable.runType == 'hubscript'}
295
380
  <div class="border">
296
381
  <FlowModuleScript path={runnable.path} />
297
382
  </div>
298
383
  {:else if runnable.runType == 'flow'}
299
- <FlowPathViewer path={runnable.path} />
384
+ {#if isHubFlowPath(runnable.path)}
385
+ {#if hubFlowPreview}
386
+ <div class="flex flex-col flex-1 h-full min-h-0 overflow-auto">
387
+ <FlowGraphViewer
388
+ triggerNode
389
+ provideTriggerContext
390
+ fillAvailableHeight
391
+ flow={{ ...hubFlowPreview, path: runnable.path }}
392
+ />
393
+ </div>
394
+ {:else}
395
+ <Skeleton layout={[[40]]} />
396
+ {/if}
397
+ {:else}
398
+ <FlowPathViewer path={runnable.path} fillAvailableHeight />
399
+ {/if}
300
400
  {:else}
301
401
  Unrecognized runType {runnable.runType}
302
402
  {/if}
@@ -1,4 +1,5 @@
1
1
  import type { ConnectedAppInput, RowAppInput, RunnableByPath, StaticAppInput, UserAppInput, CtxAppInput } from '../../inputType';
2
+ import { type OpenFlow } from '../../../../gen';
2
3
  interface Props {
3
4
  runnable: RunnableByPath;
4
5
  fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput | CtxAppInput> | undefined;
@@ -7,6 +8,7 @@ interface Props {
7
8
  isLoading?: boolean;
8
9
  onRun?: any;
9
10
  onCancel?: any;
11
+ hubFlowPreview?: OpenFlow | undefined;
10
12
  }
11
13
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
12
14
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -26,6 +28,6 @@ declare const InlineScriptRunnableByPath: $$__sveltets_2_IsomorphicComponent<Pro
26
28
  fork: CustomEvent<any>;
27
29
  } & {
28
30
  [evt: string]: CustomEvent<any>;
29
- }, {}, {}, "runnable" | "fields">;
31
+ }, {}, {}, "runnable" | "fields" | "hubFlowPreview">;
30
32
  type InlineScriptRunnableByPath = InstanceType<typeof InlineScriptRunnableByPath>;
31
33
  export default InlineScriptRunnableByPath;
@@ -5,10 +5,10 @@ import InlineScriptList from './InlineScriptList.svelte';
5
5
  import WorkspaceScriptList from './WorkspaceScriptList.svelte';
6
6
  import WorkspaceFlowList from './WorkspaceFlowList.svelte';
7
7
  import { createEventDispatcher, untrack } from 'svelte';
8
- import { schemaToInputsSpec } from '../../../utils';
9
- import { defaultIfEmptyString, emptySchema } from '../../../../../utils';
8
+ import { emptySchema } from '../../../../../utils';
10
9
  import { loadSchema } from '../../../../../infer';
11
10
  import { workspaceStore } from '../../../../../stores';
11
+ import { buildPathRunnableSelection } from './runnableSelectorUtils';
12
12
  let { defaultUserInput = false, hideCreateScript = false, onlyFlow = false, rawApps = false, unusedInlineScripts = $bindable() } = $props();
13
13
  // const { app, workspace } = getContext<AppViewerContext>('AppViewerContext')
14
14
  let tab = $state(untrack(() => onlyFlow)
@@ -27,48 +27,24 @@ async function loadSchemaFromTriggerable(path, runType) {
27
27
  return schema ?? { schema: emptySchema(), summary: undefined };
28
28
  }
29
29
  async function pickScript(path) {
30
- const schema = await loadSchemaFromTriggerable(path, 'script');
31
- const fields = schemaToInputsSpec(schema.schema, defaultUserInput);
32
- const runnable = {
33
- type: 'path',
34
- path,
35
- runType: 'script',
36
- schema: schema.schema,
37
- name: defaultIfEmptyString(schema.summary, path)
38
- };
30
+ const selection = buildPathRunnableSelection(path, 'script', await loadSchemaFromTriggerable(path, 'script'), defaultUserInput, rawApps);
39
31
  dispatch('pick', {
40
- runnable,
41
- fields
32
+ runnable: selection.runnable,
33
+ fields: selection.fields
42
34
  });
43
35
  }
44
36
  async function pickFlow(path) {
45
- const schema = await loadSchemaFromTriggerable(path, 'flow');
46
- const fields = schemaToInputsSpec(schema.schema, defaultUserInput);
47
- const runnable = {
48
- type: 'path',
49
- path,
50
- runType: 'flow',
51
- schema,
52
- name: defaultIfEmptyString(schema.summary, path)
53
- };
37
+ const selection = buildPathRunnableSelection(path, 'flow', await loadSchemaFromTriggerable(path, 'flow'), defaultUserInput, rawApps);
54
38
  dispatch('pick', {
55
- runnable,
56
- fields
39
+ runnable: selection.runnable,
40
+ fields: selection.fields
57
41
  });
58
42
  }
59
43
  async function pickHubScript(path) {
60
- const schema = await loadSchemaFromTriggerable(path, 'hubscript');
61
- const fields = schemaToInputsSpec(schema.schema, defaultUserInput);
62
- const runnable = {
63
- type: 'path',
64
- path,
65
- runType: 'hubscript',
66
- schema: schema.schema,
67
- name: defaultIfEmptyString(schema.summary, path)
68
- };
44
+ const selection = buildPathRunnableSelection(path, 'hubscript', await loadSchemaFromTriggerable(path, 'hubscript'), defaultUserInput, rawApps);
69
45
  dispatch('pick', {
70
- runnable,
71
- fields
46
+ runnable: selection.runnable,
47
+ fields: selection.fields
72
48
  });
73
49
  }
74
50
  function pickInlineScript(name) {
@@ -0,0 +1,10 @@
1
+ import type { Schema } from '../../../../../common';
2
+ import type { Runnable, StaticAppInput } from '../../../inputType';
3
+ export type LoadedRunnableSchema = {
4
+ schema: Schema;
5
+ summary: string | undefined;
6
+ };
7
+ export declare function buildPathRunnableSelection(path: string, runType: 'script' | 'flow' | 'hubscript', loadedSchema: LoadedRunnableSchema, defaultUserInput: boolean, rawApps: boolean): {
8
+ runnable: Runnable;
9
+ fields: Record<string, StaticAppInput>;
10
+ };
@@ -0,0 +1,14 @@
1
+ import { schemaToInputsSpec } from '../../../utils';
2
+ import { defaultIfEmptyString } from '../../../../../utils';
3
+ export function buildPathRunnableSelection(path, runType, loadedSchema, defaultUserInput, rawApps) {
4
+ return {
5
+ runnable: {
6
+ type: 'path',
7
+ path,
8
+ runType,
9
+ schema: loadedSchema.schema,
10
+ name: defaultIfEmptyString(loadedSchema.summary, path)
11
+ },
12
+ fields: schemaToInputsSpec(loadedSchema.schema, defaultUserInput || rawApps)
13
+ };
14
+ }