windmill-components 1.687.0 → 1.695.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/package/components/ArgInput.svelte +2 -0
  2. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  3. package/package/components/CompareWorkspaces.svelte +206 -157
  4. package/package/components/DatatableSchemaDiff.svelte +2 -2
  5. package/package/components/Dev.svelte +401 -85
  6. package/package/components/EditableSchemaForm.svelte +4 -0
  7. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  8. package/package/components/FlowPreviewContent.svelte +32 -30
  9. package/package/components/FlowRestartButton.svelte +143 -61
  10. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  11. package/package/components/FlowStatusViewer.svelte +15 -1
  12. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  13. package/package/components/FlowStatusViewerInner.svelte +1 -2
  14. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  15. package/package/components/ForkConflictModal.svelte +57 -0
  16. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  17. package/package/components/GitRepoViewer.svelte +251 -97
  18. package/package/components/InputTransformSchemaForm.svelte +1 -1
  19. package/package/components/InstanceSettings.svelte +36 -16
  20. package/package/components/Login.svelte +113 -28
  21. package/package/components/Login.svelte.d.ts +1 -0
  22. package/package/components/Path.svelte +7 -1
  23. package/package/components/Path.svelte.d.ts +1 -1
  24. package/package/components/RunsPage.svelte +2 -1
  25. package/package/components/S3FilePickerInner.svelte +89 -89
  26. package/package/components/ScriptEditor.svelte +18 -5
  27. package/package/components/ShareModal.svelte.d.ts +1 -1
  28. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  29. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  30. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  31. package/package/components/apps/editor/appPolicy.js +2 -1
  32. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  33. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  34. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  35. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  36. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  37. package/package/components/apps/inputType.d.ts +1 -0
  38. package/package/components/apps/sharedTypes.d.ts +1 -0
  39. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  40. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  41. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  42. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  43. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  44. package/package/components/copilot/chat/AIChatManager.svelte.js +48 -46
  45. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  46. package/package/components/copilot/chat/app/core.d.ts +12 -20
  47. package/package/components/copilot/chat/app/core.js +103 -160
  48. package/package/components/copilot/chat/app/core.test.js +234 -9
  49. package/package/components/copilot/chat/context.js +44 -0
  50. package/package/components/copilot/chat/flow/FlowAIChat.svelte +5 -3
  51. package/package/components/copilot/chat/flow/core.d.ts +2 -1
  52. package/package/components/copilot/chat/flow/core.js +48 -21
  53. package/package/components/copilot/chat/flow/helperUtils.d.ts +5 -2
  54. package/package/components/copilot/chat/flow/helperUtils.js +33 -1
  55. package/package/components/copilot/chat/flow/helperUtils.test.js +116 -1
  56. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  57. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  58. package/package/components/copilot/chat/script/core.js +3 -0
  59. package/package/components/copilot/chat/shared.d.ts +6 -0
  60. package/package/components/copilot/chat/shared.js +22 -1
  61. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  62. package/package/components/copilot/chat/shared.test.js +412 -0
  63. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  64. package/package/components/copilot/chat/workspaceTools.js +239 -0
  65. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  66. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  67. package/package/components/copilot/lib.js +3 -1
  68. package/package/components/copilot/lib.test.d.ts +1 -0
  69. package/package/components/copilot/lib.test.js +19 -0
  70. package/package/components/copilot/modelConfig.d.ts +3 -0
  71. package/package/components/copilot/modelConfig.js +10 -0
  72. package/package/components/flows/FlowProgressBar.svelte +5 -2
  73. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  74. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  75. package/package/components/flows/flowStateUtils.svelte.js +5 -1
  76. package/package/components/flows/map/FlowModuleSchemaMap.svelte +3 -2
  77. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -0
  78. package/package/components/git_sync/GitSyncContext.svelte.js +0 -2
  79. package/package/components/graph/FlowGraphV2.svelte +7 -3
  80. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  81. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -0
  82. package/package/components/home/deploy_ui.js +1 -1
  83. package/package/components/icons/AzureIcon.svelte +12 -25
  84. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  85. package/package/components/instanceSettings.js +24 -0
  86. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  87. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  88. package/package/components/offboarding-utils.js +2 -0
  89. package/package/components/progressBar/ProgressBar.svelte +9 -5
  90. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  91. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  92. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  93. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  94. package/package/components/raw_apps/RawAppEditor.svelte +159 -102
  95. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  96. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  97. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  98. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  99. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  100. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  101. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  102. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  103. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  104. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  105. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  106. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  107. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  108. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  109. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  110. package/package/components/resources/resourceTypesFilter.js +21 -0
  111. package/package/components/restartFromStepPath.d.ts +39 -0
  112. package/package/components/restartFromStepPath.js +89 -0
  113. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  114. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  115. package/package/components/runs/JobDetailHeader.svelte +24 -3
  116. package/package/components/runs/runsFilter.d.ts +1 -1
  117. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  118. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  119. package/package/components/search/GlobalSearchModal.svelte +8 -1
  120. package/package/components/select/Select.svelte +1 -1
  121. package/package/components/settings/CreateToken.svelte +48 -77
  122. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  123. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  124. package/package/components/settings/ScopesPicker.svelte +43 -0
  125. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  126. package/package/components/settings/TokensTable.svelte +51 -15
  127. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  128. package/package/components/sidebar/SidebarContent.svelte +11 -1
  129. package/package/components/triggers/AddTriggersButton.svelte +6 -0
  130. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  131. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  132. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  133. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  134. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  135. package/package/components/triggers/TriggersEditor.svelte +5 -1
  136. package/package/components/triggers/TriggersWrapper.svelte +10 -0
  137. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  138. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  139. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  140. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  141. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  142. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  143. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  144. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  145. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  146. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  147. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  148. package/package/components/triggers/azure/utils.js +56 -0
  149. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +2 -0
  150. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +9 -3
  151. package/package/components/triggers/http/RouteEditorInner.svelte +2 -0
  152. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +9 -3
  153. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +9 -3
  154. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +9 -3
  155. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +9 -3
  156. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +9 -3
  157. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +9 -3
  158. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  159. package/package/components/triggers/triggers.svelte.js +23 -1
  160. package/package/components/triggers/utils.js +20 -0
  161. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +9 -3
  162. package/package/components/triggers.d.ts +1 -1
  163. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  164. package/package/components/useNestedRestartState.svelte.js +320 -0
  165. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  166. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  167. package/package/gen/core/OpenAPI.js +1 -1
  168. package/package/gen/schemas.gen.d.ts +294 -24
  169. package/package/gen/schemas.gen.js +297 -25
  170. package/package/gen/services.gen.d.ts +247 -4
  171. package/package/gen/services.gen.js +498 -7
  172. package/package/gen/types.gen.d.ts +990 -37
  173. package/package/hubPaths.json +2 -5
  174. package/package/infer.d.ts +1 -1
  175. package/package/infer.js +37 -51
  176. package/package/mcpEndpointTools.js +60 -4
  177. package/package/script_helpers.js +17 -0
  178. package/package/stores.d.ts +7 -0
  179. package/package/stores.js +6 -1
  180. package/package/system_prompts/index.d.ts +1 -0
  181. package/package/system_prompts/index.js +8 -0
  182. package/package/system_prompts/prompts.d.ts +16 -13
  183. package/package/system_prompts/prompts.js +653 -43
  184. package/package/templates/ci_test_bun.ts.template +8 -0
  185. package/package/templates/ci_test_python.py.template +8 -0
  186. package/package/utils/forkConflict.d.ts +26 -0
  187. package/package/utils/forkConflict.js +56 -0
  188. package/package/utils_deployable.d.ts +164 -121
  189. package/package/utils_deployable.js +61 -11
  190. package/package/utils_workspace_deploy.js +3 -1
  191. package/package.json +29 -5
  192. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  193. package/dist/sharedUtils/base.d.ts +0 -1
  194. package/dist/sharedUtils/cloud.d.ts +0 -1
  195. package/dist/sharedUtils/common.d.ts +0 -111
  196. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  197. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  198. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  199. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  200. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  201. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  202. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  203. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  204. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  205. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  206. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  207. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  208. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  209. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  210. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  211. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  212. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  213. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  214. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  215. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  216. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  217. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  218. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  219. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  220. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  221. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  222. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  223. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  224. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  225. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  226. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  227. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  228. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  229. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  230. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  231. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  232. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  233. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  234. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  235. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  236. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  237. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  238. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  239. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  240. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  241. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  242. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  243. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  244. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  245. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  246. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  247. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  248. package/dist/sharedUtils/gen/index.d.ts +0 -6
  249. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  250. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  251. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  252. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  253. package/dist/sharedUtils/hub.d.ts +0 -49
  254. package/dist/sharedUtils/jsr.json +0 -6
  255. package/dist/sharedUtils/lib.d.ts +0 -5
  256. package/dist/sharedUtils/lib.es.js +0 -1588
  257. package/dist/sharedUtils/package.json +0 -12
  258. package/dist/sharedUtils/schema.d.ts +0 -3
  259. package/dist/sharedUtils/stores.d.ts +0 -97
  260. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  261. package/dist/sharedUtils/toast.d.ts +0 -8
  262. package/dist/sharedUtils/utils.d.ts +0 -265
  263. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  264. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
@@ -12,7 +12,7 @@ import RunBadges from './RunBadges.svelte';
12
12
  import WorkerHostname from '../WorkerHostname.svelte';
13
13
  import Button from '../common/button/Button.svelte';
14
14
  import DropdownV2 from '../DropdownV2.svelte';
15
- import { getRelevantFields, getTriggerInfo } from './JobDetailFieldConfig';
15
+ import { getRelevantFields, getTriggerInfo, isFlowVersionHash } from './JobDetailFieldConfig';
16
16
  import { flowPathToHref } from '../../scripts';
17
17
  import { slide } from 'svelte/transition';
18
18
  import { twMerge } from 'tailwind-merge';
@@ -60,7 +60,8 @@ function getTruncatedValue(config, job, compact = false) {
60
60
  case 'run_id':
61
61
  return truncateRev(fullValue, 8);
62
62
  case 'script_hash':
63
- return truncateHash(fullValue.toString());
63
+ // truncateHash drops leading digits of a decimal version id; skip it.
64
+ return isFlowVersionHash(job) ? fullValue.toString() : truncateHash(fullValue.toString());
64
65
  case 'parent_job':
65
66
  return truncateRev(fullValue, 6);
66
67
  case 'schedule_path':
@@ -164,6 +165,8 @@ function getJobKindDisplayName(job) {
164
165
  {/snippet}
165
166
  <a
166
167
  href={`${base}/runs/?job_kinds=all&worker=${job?.worker}`}
168
+ target="_blank"
169
+ rel="noopener noreferrer"
167
170
  class="flex items-center gap-1 text-primary"
168
171
  >
169
172
  <span class="truncate flex-shrink min-w-0">{displayValue}</span>
@@ -199,6 +202,8 @@ function getJobKindDisplayName(job) {
199
202
  {/if}
200
203
  <a
201
204
  href={`${base}/run/${job.parent_job}?workspace=${$workspaceStore}`}
205
+ target="_blank"
206
+ rel="noopener noreferrer"
202
207
  class="flex items-center gap-1"
203
208
  >
204
209
  {displayValue}
@@ -245,8 +250,18 @@ function getJobKindDisplayName(job) {
245
250
  {:else if href}
246
251
  <a
247
252
  {href}
253
+ target="_blank"
254
+ rel="noopener noreferrer"
248
255
  class="flex items-center gap-1 min-w-0 text-primary"
249
- title={config.field === 'script_hash' ? `Script hash: ${fullValue}` : fullValue}
256
+ title={config.field === 'script_hash'
257
+ ? `${
258
+ job.job_kind === 'appdependencies'
259
+ ? 'App version'
260
+ : isFlowVersionHash(job)
261
+ ? 'Flow version'
262
+ : 'Script hash'
263
+ }: ${fullValue}`
264
+ : fullValue}
250
265
  >
251
266
  <span class="truncate flex-shrink min-w-0">{displayValue}</span>
252
267
  <ExternalLink size={12} class="flex-shrink-0" />
@@ -268,6 +283,8 @@ function getJobKindDisplayName(job) {
268
283
  <span class="text-primary">
269
284
  <a
270
285
  href={`${base}/run/${job.id}?workspace=${job.workspace_id}`}
286
+ target="_blank"
287
+ rel="noopener noreferrer"
271
288
  class="flex items-center gap-1 min-w-0"
272
289
  >
273
290
  <span class="truncate flex-shrink min-w-0">{truncateRev(job.id, 8)}</span>
@@ -360,6 +377,8 @@ function getJobKindDisplayName(job) {
360
377
  : flowPathToHref(job?.script_path ?? '')}
361
378
  <a
362
379
  href={viewHref}
380
+ target="_blank"
381
+ rel="noopener noreferrer"
363
382
  class="text-emphasis {compact
364
383
  ? 'text-xs'
365
384
  : 'text-lg'} font-semibold flex items-center gap-1"
@@ -449,6 +468,8 @@ function getJobKindDisplayName(job) {
449
468
  <span class="text-primary">
450
469
  <a
451
470
  href={`${base}/run/${job.id}?workspace=${job.workspace_id}`}
471
+ target="_blank"
472
+ rel="noopener noreferrer"
452
473
  class="flex items-center gap-1 min-w-0"
453
474
  >
454
475
  <span class="truncate flex-shrink min-w-0">{truncateRev(job.id, 8)}</span>
@@ -178,7 +178,7 @@ export declare function buildRunsFilterSearchbarSchema({ paths, usernames, folde
178
178
  label: string;
179
179
  icon: typeof Zap;
180
180
  options: {
181
- label: "Google" | "GitHub" | "Schedule" | "HTTP" | "WebSocket" | "Postgres" | "Kafka" | "NATS" | "MQTT" | "SQS" | "GCP Pub/Sub" | "Email" | "Webhook" | "Default Email";
181
+ label: "Google" | "GitHub" | "Schedule" | "HTTP" | "WebSocket" | "Postgres" | "Kafka" | "NATS" | "MQTT" | "SQS" | "GCP Pub/Sub" | "Azure Event Grid" | "Email" | "Webhook" | "Default Email";
182
182
  value: JobTriggerKind;
183
183
  }[];
184
184
  allowNegative: true;
@@ -13,7 +13,10 @@ import { Pen, Plus, Trash2 } from 'lucide-svelte';
13
13
  import Popover from '../meltComponents/Popover.svelte';
14
14
  import ResourcePicker from '../ResourcePicker.svelte';
15
15
  import { DynamicInput } from '../../utils';
16
- let { format = $bindable(undefined), contentEncoding = undefined, type = undefined, oneOf = $bindable(undefined), required = false, pattern = undefined, password = undefined, variableEditor = undefined, itemPicker = undefined, nullable = $bindable(undefined), disabled = $bindable(undefined), defaultValue = $bindable(undefined), propsNames = [], showExpr = $bindable(undefined), extra = {}, customErrorMessage = undefined, itemsType = undefined, properties = $bindable(undefined), order = $bindable(undefined), requiredProperty = $bindable(undefined), displayWebhookWarning = true, onDrawerClose = undefined } = $props();
16
+ let { format = $bindable(undefined), contentEncoding = undefined, type = undefined, oneOf = $bindable(undefined), required = false, pattern = undefined, password = undefined, variableEditor = undefined, itemPicker = undefined, nullable = $bindable(undefined), disabled = $bindable(undefined), defaultValue = $bindable(undefined), propsNames = [], showExpr = $bindable(undefined), extra = {}, customErrorMessage = undefined, itemsType = undefined, properties = $bindable(undefined), order = $bindable(undefined), requiredProperty = $bindable(undefined), displayWebhookWarning = true, onDrawerClose = undefined, hideCatalogPicker = $bindable(undefined), hideRawInput = $bindable(undefined) } = $props();
17
+ let isS3Field = $derived(format === 'resource-s3_object' ||
18
+ (type === 'array' &&
19
+ (itemsType?.resourceType === 's3_object' || itemsType?.resourceType === 's3object')));
17
20
  let oneOfSelected = $state(oneOf?.[0]?.title);
18
21
  $effect(() => {
19
22
  if (oneOf?.length && !oneOfSelected) {
@@ -351,6 +354,32 @@ let customObjectSelected = $state(format?.startsWith('jsonschema-') ? 'json-sche
351
354
  }
352
355
  }}
353
356
  />
357
+ {#if isS3Field}
358
+ <Toggle
359
+ options={{
360
+ right: 'Hide catalog picker',
361
+ rightTooltip: 'Hide the "Choose an object from the catalog" button below the file upload.'
362
+ }}
363
+ lightMode
364
+ size="xs"
365
+ checked={hideCatalogPicker}
366
+ on:change={(event) => {
367
+ hideCatalogPicker = event?.detail ? true : undefined
368
+ }}
369
+ />
370
+ <Toggle
371
+ options={{
372
+ right: 'Hide raw input',
373
+ rightTooltip: 'Hide the "Raw S3 object input" toggle below the file upload.'
374
+ }}
375
+ lightMode
376
+ size="xs"
377
+ checked={hideRawInput}
378
+ on:change={(event) => {
379
+ hideRawInput = event?.detail ? true : undefined
380
+ }}
381
+ />
382
+ {/if}
354
383
  </div>
355
384
 
356
385
  {#if displayWebhookWarning && !(type === 'object' && oneOf && oneOf.length >= 2)}
@@ -19,16 +19,19 @@ interface Props {
19
19
  extra?: Record<string, any>;
20
20
  customErrorMessage?: string | undefined;
21
21
  itemsType?: {
22
- type?: 'string' | 'number' | 'bytes' | 'object';
22
+ type?: 'string' | 'number' | 'bytes' | 'object' | 'resource';
23
23
  contentEncoding?: 'base64';
24
24
  enum?: string[];
25
25
  multiselect?: string[];
26
+ resourceType?: string;
26
27
  } | undefined;
27
28
  properties?: Record<string, any> | undefined;
28
29
  order?: string[] | undefined;
29
30
  requiredProperty?: string[] | undefined;
30
31
  displayWebhookWarning?: boolean;
31
32
  onDrawerClose?: () => void;
33
+ hideCatalogPicker?: boolean | undefined;
34
+ hideRawInput?: boolean | undefined;
32
35
  }
33
36
  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> {
34
37
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -47,6 +50,6 @@ declare const FlowPropertyEditor: $$__sveltets_2_IsomorphicComponent<Props, {
47
50
  requiredChange: CustomEvent<any>;
48
51
  } & {
49
52
  [evt: string]: CustomEvent<any>;
50
- }, {}, {}, "disabled" | "format" | "order" | "defaultValue" | "properties" | "oneOf" | "nullable" | "showExpr" | "requiredProperty">;
53
+ }, {}, {}, "disabled" | "format" | "order" | "defaultValue" | "properties" | "oneOf" | "nullable" | "hideCatalogPicker" | "hideRawInput" | "showExpr" | "requiredProperty">;
51
54
  type FlowPropertyEditor = InstanceType<typeof FlowPropertyEditor>;
52
55
  export default FlowPropertyEditor;
@@ -13,7 +13,7 @@ import BarsStaggered from '../icons/BarsStaggered.svelte';
13
13
  import { Alert } from '../common';
14
14
  import Popover from '../Popover.svelte';
15
15
  import Logs from 'lucide-svelte/icons/logs';
16
- import { AwsIcon, GoogleCloudIcon, KafkaIcon, MqttIcon, NatsIcon } from '../icons';
16
+ import { AwsIcon, AzureIcon, GoogleCloudIcon, KafkaIcon, MqttIcon, NatsIcon } from '../icons';
17
17
  import RunsSearch from './RunsSearch.svelte';
18
18
  import AskAiButton from '../copilot/AskAiButton.svelte';
19
19
  let open = $state(false);
@@ -95,6 +95,13 @@ let hiddenMenuItems = [
95
95
  icon: GoogleCloudIcon,
96
96
  disabled: $userStore?.operator
97
97
  },
98
+ {
99
+ search_id: 'nav:azure_event_grid',
100
+ label: 'Go to Azure Event Grid' + (!$enterpriseLicense ? '' : ' (EE)'),
101
+ action: (newtab = false) => gotoPage('/azure_triggers', newtab),
102
+ icon: AzureIcon,
103
+ disabled: $userStore?.operator
104
+ },
98
105
  {
99
106
  search_id: 'nav:mqtt_triggers',
100
107
  label: 'Go to MQTT triggers',
@@ -74,7 +74,7 @@ let inputText = $derived.by(() => {
74
74
  />
75
75
  </div>
76
76
  {:else if RightIcon}
77
- <div class="absolute z-10 right-2 h-full flex items-center">
77
+ <div class="absolute z-10 right-2 h-full flex items-center pointer-events-none">
78
78
  <RightIcon size={iconSize} class="text-secondary" />
79
79
  </div>
80
80
  {/if}
@@ -5,8 +5,7 @@ import { triggerableByAI } from '../../actions/triggerableByAI.svelte';
5
5
  import Toggle from '../Toggle.svelte';
6
6
  import { UserService } from '../../gen';
7
7
  import TokenDisplay from './TokenDisplay.svelte';
8
- import ScopeSelector from './ScopeSelector.svelte';
9
- import McpScopeSelector from '../mcp/McpScopeSelector.svelte';
8
+ import ScopesPicker from './ScopesPicker.svelte';
10
9
  import TextInput from '../text_input/TextInput.svelte';
11
10
  import Select from '../select/Select.svelte';
12
11
  let { showMcpMode = false, openWithMcpMode = false, mcpOnly = false, lockWorkspace = false, title = 'Add a new token', defaultNewTokenWorkspace, scopes, onTokenCreated, newTokenLabel = $bindable(undefined), displayCreateToken = true } = $props();
@@ -15,11 +14,9 @@ let newMcpToken = $state(undefined);
15
14
  let newTokenExpiration = $state(undefined);
16
15
  let newTokenWorkspace = $state(untrack(() => defaultNewTokenWorkspace));
17
16
  let mcpCreationMode = $state(false);
18
- let mcpScope = $state('mcp:favorites');
19
17
  let lastRequestedMcpMode = $state(undefined);
20
18
  let mcpLabelAutofilled = $state(false);
21
- let customScopes = $state([]);
22
- let showCustomScopes = $state(false);
19
+ let pickedScopes = $state(null);
23
20
  function ensureCurrentWorkspaceIncluded(workspacesList, currentWorkspace) {
24
21
  if (!currentWorkspace) {
25
22
  return workspacesList;
@@ -60,13 +57,7 @@ async function createToken(mcpMode = false) {
60
57
  if (newTokenExpiration) {
61
58
  date = new Date(new Date().getTime() + newTokenExpiration * 1000);
62
59
  }
63
- let tokenScopes = scopes;
64
- if (mcpMode) {
65
- tokenScopes = mcpScope.split(' ').filter((s) => s.length > 0);
66
- }
67
- else if (showCustomScopes && customScopes.length > 0) {
68
- tokenScopes = customScopes;
69
- }
60
+ const tokenScopes = scopes ?? pickedScopes ?? undefined;
70
61
  const createdToken = await UserService.createToken({
71
62
  requestBody: {
72
63
  label: newTokenLabel,
@@ -155,77 +146,58 @@ $effect(() => {
155
146
  </div>
156
147
  {/if}
157
148
 
158
- {#if !mcpCreationMode && (!scopes || scopes.length === 0)}
159
- <div class="flex flex-col gap-2">
160
- <Toggle
161
- checked={showCustomScopes}
162
- on:change={(e) => {
163
- showCustomScopes = e.detail
164
- }}
165
- options={{
166
- right: 'Limit token permissions',
167
- rightTooltip:
168
- 'By default, tokens have full API access. Enable this to restrict the token to specific scopes.'
169
- }}
170
- size="xs"
171
- />
172
- {#if showCustomScopes}
173
- <ScopeSelector bind:selectedScopes={customScopes} />
174
- {/if}
175
- </div>
149
+ {#if !scopes || scopes.length === 0}
150
+ <ScopesPicker
151
+ mode={mcpCreationMode ? 'mcp' : 'standard'}
152
+ workspaceId={newTokenWorkspace || $workspaceStore || ''}
153
+ bind:value={pickedScopes}
154
+ />
176
155
  {/if}
177
156
 
178
157
  <div class="mt-2 grid grid-cols-1 md:grid-cols-2 gap-4">
179
- {#if mcpCreationMode}
180
- <div class="col-span-2">
181
- <McpScopeSelector
182
- workspaceId={newTokenWorkspace || $workspaceStore || ''}
183
- bind:scope={mcpScope}
184
- />
185
- </div>
186
-
187
- {#if !lockWorkspace}
188
- <div>
189
- <span class="block mb-1 text-emphasis text-xs font-semibold">Workspace</span>
190
- <Select
191
- bind:value={newTokenWorkspace}
192
- items={workspaces.map((w) => ({ label: w.name, value: w.id, subtitle: w.id }))}
193
- />
194
- </div>
195
- {/if}
196
- {/if}
197
-
198
- {#if !mcpOnly}
199
- <div>
200
- <span class="block mb-1 text-emphasis text-xs font-semibold"
201
- >Label <span class="text-xs text-primary">(optional)</span></span
202
- >
203
- <TextInput inputProps={{ type: 'text' }} bind:value={newTokenLabel} class="w-full" />
204
- </div>
205
- {/if}
206
-
207
- {#if !mcpCreationMode}
158
+ {#if mcpCreationMode}
159
+ {#if !lockWorkspace}
208
160
  <div>
209
- <span class="block mb-1 text-xs text-emphasis font-semibold"
210
- >Expires In <span class="text-xs text-primary">(optional)</span></span
211
- >
161
+ <span class="block mb-1 text-emphasis text-xs font-semibold">Workspace</span>
212
162
  <Select
213
- bind:value={newTokenExpiration}
214
- placeholder="No expiration"
215
- inputClass="w-full"
216
- items={[
217
- { label: 'No expiration', value: undefined },
218
- { label: '15 minutes', value: 15 * 60 },
219
- { label: '30 minutes', value: 30 * 60 },
220
- { label: '1 hour', value: 1 * 60 * 60 },
221
- { label: '1 day', value: 1 * 24 * 60 * 60 },
222
- { label: '7 days', value: 7 * 24 * 60 * 60 },
223
- { label: '30 days', value: 30 * 24 * 60 * 60 },
224
- { label: '90 days', value: 90 * 24 * 60 * 60 }
225
- ]}
163
+ bind:value={newTokenWorkspace}
164
+ items={workspaces.map((w) => ({ label: w.name, value: w.id, subtitle: w.id }))}
226
165
  />
227
166
  </div>
228
167
  {/if}
168
+ {/if}
169
+
170
+ {#if !mcpOnly}
171
+ <div>
172
+ <span class="block mb-1 text-emphasis text-xs font-semibold"
173
+ >Label <span class="text-xs text-primary">(optional)</span></span
174
+ >
175
+ <TextInput inputProps={{ type: 'text' }} bind:value={newTokenLabel} class="w-full" />
176
+ </div>
177
+ {/if}
178
+
179
+ {#if !mcpCreationMode}
180
+ <div>
181
+ <span class="block mb-1 text-xs text-emphasis font-semibold"
182
+ >Expires In <span class="text-xs text-primary">(optional)</span></span
183
+ >
184
+ <Select
185
+ bind:value={newTokenExpiration}
186
+ placeholder="No expiration"
187
+ inputClass="w-full"
188
+ items={[
189
+ { label: 'No expiration', value: undefined },
190
+ { label: '15 minutes', value: 15 * 60 },
191
+ { label: '30 minutes', value: 30 * 60 },
192
+ { label: '1 hour', value: 1 * 60 * 60 },
193
+ { label: '1 day', value: 1 * 24 * 60 * 60 },
194
+ { label: '7 days', value: 7 * 24 * 60 * 60 },
195
+ { label: '30 days', value: 30 * 24 * 60 * 60 },
196
+ { label: '90 days', value: 90 * 24 * 60 * 60 }
197
+ ]}
198
+ />
199
+ </div>
200
+ {/if}
229
201
  </div>
230
202
 
231
203
  <div class="mt-4 flex justify-end gap-2 flex-row">
@@ -241,8 +213,7 @@ $effect(() => {
241
213
  {/if}
242
214
  <Button
243
215
  on:click={() => createToken(mcpCreationMode)}
244
- disabled={mcpCreationMode &&
245
- (newTokenWorkspace == undefined || !mcpScope || mcpScope.trim().length === 0)}
216
+ disabled={mcpCreationMode && (newTokenWorkspace == undefined || !pickedScopes)}
246
217
  variant="accent"
247
218
  >
248
219
  {mcpCreationMode ? 'Generate MCP URL' : 'New token'}
@@ -0,0 +1,57 @@
1
+ <script lang="ts">import { UserService } from '../../gen';
2
+ import { sendUserToast } from '../../toast';
3
+ import { workspaceStore } from '../../stores';
4
+ import Button from '../common/button/Button.svelte';
5
+ import Modal from '../common/modal/Modal.svelte';
6
+ import ScopesPicker from './ScopesPicker.svelte';
7
+ let { open = $bindable(), tokenPrefix, initialScopes, tokenWorkspaceId, onSaved } = $props();
8
+ // Treat as MCP only when *all* existing scopes are mcp:* — mixed-scope or
9
+ // null-scope tokens fall back to the standard picker so non-MCP scopes are
10
+ // never silently dropped.
11
+ const isMcp = $derived((initialScopes ?? []).length > 0 && (initialScopes ?? []).every((s) => s.startsWith('mcp:')));
12
+ const mcpWorkspaceId = $derived(tokenWorkspaceId ?? $workspaceStore ?? '');
13
+ let pickedScopes = $state(null);
14
+ let saving = $state(false);
15
+ async function save() {
16
+ if (!tokenPrefix)
17
+ return;
18
+ saving = true;
19
+ try {
20
+ await UserService.updateTokenScopes({
21
+ tokenPrefix,
22
+ requestBody: { scopes: pickedScopes }
23
+ });
24
+ sendUserToast('Token scopes updated');
25
+ onSaved?.();
26
+ open = false;
27
+ }
28
+ catch (err) {
29
+ sendUserToast(`Failed to update scopes: ${err.body ?? err.message}`, true);
30
+ }
31
+ finally {
32
+ saving = false;
33
+ }
34
+ }
35
+ const saveDisabled = $derived(saving || !tokenPrefix || (isMcp && !pickedScopes));
36
+ </script>
37
+
38
+ <Modal bind:open title="Edit token scopes" class="!max-w-3xl">
39
+ <div class="flex flex-col gap-3">
40
+ <div class="text-xs text-secondary">
41
+ Token <span class="font-mono">{tokenPrefix}****</span>
42
+ </div>
43
+
44
+ {#key tokenPrefix}
45
+ <ScopesPicker
46
+ mode={isMcp ? 'mcp' : 'standard'}
47
+ workspaceId={mcpWorkspaceId}
48
+ {initialScopes}
49
+ bind:value={pickedScopes}
50
+ />
51
+ {/key}
52
+ </div>
53
+
54
+ {#snippet actions()}
55
+ <Button size="sm" variant="accent" disabled={saveDisabled} on:click={save}>Save</Button>
56
+ {/snippet}
57
+ </Modal>
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ open: boolean;
3
+ tokenPrefix?: string;
4
+ initialScopes?: string[];
5
+ tokenWorkspaceId?: string;
6
+ onSaved?: () => void;
7
+ }
8
+ declare const EditTokenScopesModal: import("svelte").Component<Props, {}, "open">;
9
+ type EditTokenScopesModal = ReturnType<typeof EditTokenScopesModal>;
10
+ export default EditTokenScopesModal;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">import Toggle from '../Toggle.svelte';
2
+ import ScopeSelector from './ScopeSelector.svelte';
3
+ import McpScopeSelector from '../mcp/McpScopeSelector.svelte';
4
+ let { mode, workspaceId = '', initialScopes, value = $bindable() } = $props();
5
+ const initialMcpScope = $derived((initialScopes ?? []).length > 0 ? (initialScopes ?? []).join(' ') : undefined);
6
+ // Standard-mode local state, seeded from initialScopes if any.
7
+ let limited = $state((initialScopes ?? []).length > 0);
8
+ let standardScopes = $state([...(initialScopes ?? [])]);
9
+ // MCP-mode local state. When no initial scope is provided we fall back
10
+ // to `mcp:favorites` (matches the create-token default).
11
+ let mcpScope = $state(initialMcpScope ?? 'mcp:favorites');
12
+ $effect(() => {
13
+ if (mode === 'mcp') {
14
+ const parts = mcpScope
15
+ .split(' ')
16
+ .map((s) => s.trim())
17
+ .filter((s) => s.length > 0);
18
+ value = parts.length > 0 ? parts : null;
19
+ }
20
+ else {
21
+ value = limited && standardScopes.length > 0 ? standardScopes : null;
22
+ }
23
+ });
24
+ </script>
25
+
26
+ {#if mode === 'standard'}
27
+ <div class="flex flex-col gap-2">
28
+ <Toggle
29
+ bind:checked={limited}
30
+ options={{
31
+ right: 'Limit token permissions',
32
+ rightTooltip:
33
+ 'When off, the token has full API access. Turn on to restrict it to specific scopes.'
34
+ }}
35
+ size="xs"
36
+ />
37
+ {#if limited}
38
+ <ScopeSelector bind:selectedScopes={standardScopes} />
39
+ {/if}
40
+ </div>
41
+ {:else}
42
+ <McpScopeSelector {workspaceId} bind:scope={mcpScope} initialScope={initialMcpScope} />
43
+ {/if}
@@ -0,0 +1,11 @@
1
+ interface Props {
2
+ mode: 'standard' | 'mcp';
3
+ workspaceId?: string;
4
+ /** Existing scopes (used for both initial standard selection and parsing MCP scope) */
5
+ initialScopes?: string[];
6
+ /** Final scope value: null = unrestricted/full access, array = explicit list */
7
+ value: string[] | null;
8
+ }
9
+ declare const ScopesPicker: import("svelte").Component<Props, {}, "value">;
10
+ type ScopesPicker = ReturnType<typeof ScopesPicker>;
11
+ export default ScopesPicker;
@@ -4,15 +4,18 @@ import { displayDate } from '../../utils';
4
4
  import { UserService } from '../../gen';
5
5
  import { sendUserToast } from '../../toast';
6
6
  import CreateToken from './CreateToken.svelte';
7
+ import EditTokenScopesModal from './EditTokenScopesModal.svelte';
7
8
  import Button from '../common/button/Button.svelte';
8
9
  import Badge from '../common/badge/Badge.svelte';
9
10
  import Alert from '../common/alert/Alert.svelte';
10
- import { Trash } from 'lucide-svelte';
11
+ import { Pen, Trash } from 'lucide-svelte';
11
12
  let { showMcpMode = false, openWithMcpMode = false, defaultNewTokenLabel, defaultNewTokenWorkspace, scopes, onTokenCreated } = $props();
12
13
  // --- Local State ---
13
14
  let tokens = $state([]);
14
15
  let tokenPage = $state(1);
15
16
  let newTokenLabel = $state(untrack(() => defaultNewTokenLabel));
17
+ let editingToken = $state(undefined);
18
+ let editModalOpen = $state(false);
16
19
  $effect(() => {
17
20
  listTokens();
18
21
  });
@@ -69,6 +72,14 @@ async function handleDeleteClick(tokenPrefix) {
69
72
  sendUserToast('Successfully deleted token');
70
73
  listTokens();
71
74
  }
75
+ function handleEditClick(tokenPrefix, tokenScopes, tokenWorkspaceId) {
76
+ editingToken = {
77
+ prefix: tokenPrefix,
78
+ scopes: tokenScopes,
79
+ workspaceId: tokenWorkspaceId
80
+ };
81
+ editModalOpen = true;
82
+ }
72
83
  async function listTokens() {
73
84
  tokens = await UserService.listTokens({
74
85
  excludeEphemeral: true,
@@ -93,7 +104,11 @@ function handlePreviousPage() {
93
104
  </div>
94
105
  {#if expiringSoonCount > 0}
95
106
  <div class="mb-2">
96
- <Alert type="warning" title="{expiringSoonCount} token{expiringSoonCount > 1 ? 's' : ''} expiring within 7 days" size="xs" />
107
+ <Alert
108
+ type="warning"
109
+ title="{expiringSoonCount} token{expiringSoonCount > 1 ? 's' : ''} expiring within 7 days"
110
+ size="xs"
111
+ />
97
112
  </div>
98
113
  {/if}
99
114
  <CreateToken
@@ -106,20 +121,19 @@ function handlePreviousPage() {
106
121
  />
107
122
  <div class="overflow-auto grow min-h-64 max-h-2/3">
108
123
  <TableCustom>
109
-
110
124
  {#snippet headerRow()}
111
- <tr >
125
+ <tr>
112
126
  <th>Prefix</th>
113
127
  <th>Label</th>
114
128
  <th>Expiration</th>
115
129
  <th>Scopes</th>
116
130
  <th></th>
117
131
  </tr>
118
- {/snippet}
132
+ {/snippet}
119
133
  {#snippet body()}
120
134
  <tbody>
121
135
  {#if tokens && tokens.length > 0}
122
- {#each tokens as { token_prefix, expiration, label, scopes } (token_prefix)}
136
+ {#each tokens as { token_prefix, expiration, label, scopes, workspace_id } (token_prefix)}
123
137
  {@const badge = expirationBadge(expiration, label)}
124
138
  <tr>
125
139
  <td class="w-32 text-xs text-primary">{token_prefix}****</td>
@@ -136,15 +150,29 @@ function handlePreviousPage() {
136
150
  class="min-w-0 max-w-48 truncate text-xs text-secondary"
137
151
  title={scopes?.join(', ') ?? ''}>{scopes?.join(', ') ?? ''}</td
138
152
  >
139
- <td class="w-16 text-center">
140
- <Button
141
- variant="subtle"
142
- destructive
143
- on:click={() => handleDeleteClick(token_prefix)}
144
- size="xs"
145
- startIcon={{ icon: Trash }}
146
- iconOnly
147
- />
153
+ <td class="w-24 text-center">
154
+ <div class="flex items-center justify-center gap-1">
155
+ <Button
156
+ variant="subtle"
157
+ on:click={() =>
158
+ handleEditClick(
159
+ token_prefix,
160
+ scopes ?? undefined,
161
+ workspace_id ?? undefined
162
+ )}
163
+ size="xs"
164
+ startIcon={{ icon: Pen }}
165
+ iconOnly
166
+ />
167
+ <Button
168
+ variant="subtle"
169
+ destructive
170
+ on:click={() => handleDeleteClick(token_prefix)}
171
+ size="xs"
172
+ startIcon={{ icon: Trash }}
173
+ iconOnly
174
+ />
175
+ </div>
148
176
  </td>
149
177
  </tr>
150
178
  {/each}
@@ -168,3 +196,11 @@ function handlePreviousPage() {
168
196
  </div>
169
197
  </div>
170
198
  </div>
199
+
200
+ <EditTokenScopesModal
201
+ bind:open={editModalOpen}
202
+ tokenPrefix={editingToken?.prefix}
203
+ initialScopes={editingToken?.scopes}
204
+ tokenWorkspaceId={editingToken?.workspaceId}
205
+ onSaved={listTokens}
206
+ />
@@ -102,6 +102,12 @@ let allTriggerLinks = $derived([
102
102
  href: `${base}/gcp_triggers`,
103
103
  kind: 'gcp'
104
104
  },
105
+ {
106
+ label: 'Azure Event Grid triggers',
107
+ id: 'triggers',
108
+ href: `${base}/azure_triggers`,
109
+ kind: 'azure'
110
+ },
105
111
  { label: 'MQTT triggers', id: 'triggers', href: `${base}/mqtt_triggers`, kind: 'mqtt' },
106
112
  { label: 'Email triggers', id: 'triggers', href: `${base}/email_triggers`, kind: 'email' }
107
113
  ].filter(filterLink));
@@ -25,6 +25,7 @@ import { getAvailableNativeTriggerServices, getServiceConfig, getServiceIcon } f
25
25
  import { Menubar, Menu, MenuSingleItem, MenuItem, MeltButton } from '../meltComponents';
26
26
  import MenuButton from './MenuButton.svelte';
27
27
  import GoogleCloudIcon from '../icons/GoogleCloudIcon.svelte';
28
+ import AzureIcon from '../icons/AzureIcon.svelte';
28
29
  async function leaveWorkspace() {
29
30
  await WorkspaceService.leaveWorkspace({ workspace: $workspaceStore ?? '' });
30
31
  sendUserToast('You left the workspace');
@@ -36,7 +37,7 @@ async function loadForkedDatatables() {
36
37
  if (!$workspaceStore)
37
38
  return;
38
39
  try {
39
- const settings = await WorkspaceService.getSettings({ workspace: $workspaceStore });
40
+ const settings = await WorkspaceService.getPublicSettings({ workspace: $workspaceStore });
40
41
  const datatables = settings.datatable?.datatables ?? {};
41
42
  forkedDatatables = Object.entries(datatables)
42
43
  .filter(([_, dt]) => dt.forked_from != null)
@@ -286,6 +287,15 @@ let defaultExtraTriggerLinks = $derived([
286
287
  aiId: 'sidebar-menu-link-gcp',
287
288
  aiDescription: 'Button to navigate to GCP Pub/Sub triggers'
288
289
  },
290
+ {
291
+ label: 'Azure Event Grid' + ($enterpriseLicense ? '' : ' (EE)'),
292
+ href: '/azure_triggers',
293
+ icon: AzureIcon,
294
+ disabled: $userStore?.operator || !$enterpriseLicense,
295
+ kind: 'azure',
296
+ aiId: 'sidebar-menu-link-azure',
297
+ aiDescription: 'Button to navigate to Azure Event Grid triggers'
298
+ },
289
299
  {
290
300
  label: 'MQTT',
291
301
  href: '/mqtt_triggers',