windmill-components 1.687.0 → 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 (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 +28 -4
  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
@@ -20,7 +20,7 @@ import Skeleton from './common/skeleton/Skeleton.svelte';
20
20
  import Button from './common/button/Button.svelte';
21
21
  import { sameTopDomainOrigin } from '../cookies';
22
22
  import { isValidLogoutRedirect } from '../logoutRedirect';
23
- let { rd = undefined, email = $bindable(undefined), password = $bindable(undefined), error = undefined, popup = false, firstTime = false, onLoginSuccess = undefined } = $props();
23
+ let { rd = undefined, email = $bindable(undefined), password = $bindable(undefined), error = undefined, popup = false, firstTime = false, autoRedirect = true, onLoginSuccess = undefined } = $props();
24
24
  const providers = [
25
25
  {
26
26
  type: 'github',
@@ -69,6 +69,8 @@ let logins = $state(undefined);
69
69
  let saml = $state(undefined);
70
70
  let smtpConfigured = $state(undefined);
71
71
  let disablePasswordLogin = $state(false);
72
+ let autoRedirecting = $state(false);
73
+ let oauthFlowDone = false;
72
74
  async function login() {
73
75
  if (!email || !password) {
74
76
  sendUserToast('Please fill in both email and password', true);
@@ -167,12 +169,14 @@ async function loadLogins() {
167
169
  disablePasswordLogin = false;
168
170
  console.error('Could not load password login setting', disabledResult.reason);
169
171
  }
172
+ let autoLogin = undefined;
170
173
  if (loginsResult.status === 'fulfilled') {
171
174
  logins = loginsResult.value.oauth.map((login) => ({
172
175
  type: login.type,
173
176
  displayName: login.display_name || login.type
174
177
  }));
175
178
  saml = loginsResult.value.saml;
179
+ autoLogin = loginsResult.value.auto_login;
176
180
  }
177
181
  else {
178
182
  logins = [];
@@ -182,6 +186,29 @@ async function loadLogins() {
182
186
  showPassword =
183
187
  !disablePasswordLogin &&
184
188
  ((logins?.length === 0 && !saml) || (email != undefined && email.length > 0));
189
+ if (autoRedirect && autoLogin && !error && !shouldSkipAutoRedirect()) {
190
+ if (autoLogin === 'saml' && saml) {
191
+ autoRedirecting = true;
192
+ if (!redirectSaml())
193
+ autoRedirecting = false;
194
+ }
195
+ else if (logins?.some((l) => l.type === autoLogin)) {
196
+ autoRedirecting = true;
197
+ if (!storeRedirect(autoLogin)) {
198
+ autoRedirecting = false;
199
+ sendUserToast('Popup blocked — please click the sign-in button to continue.', true);
200
+ }
201
+ }
202
+ }
203
+ }
204
+ function shouldSkipAutoRedirect() {
205
+ try {
206
+ const params = new URLSearchParams(window.location.search);
207
+ return params.get('no_sso') === '1';
208
+ }
209
+ catch {
210
+ return false;
211
+ }
185
212
  }
186
213
  loadLogins();
187
214
  $effect(() => {
@@ -233,17 +260,23 @@ function processPopupData(data) {
233
260
  sendUserToast(data.error, true);
234
261
  }
235
262
  else if (data.type === 'success') {
236
- onLoginSuccess?.();
263
+ finishOauthFlow('postMessage');
237
264
  }
238
265
  }
239
266
  function handleStorageEvent(event) {
240
267
  if (event.key === 'oauth-success') {
241
268
  try {
242
- processPopupData(JSON.parse(event.newValue));
269
+ const data = JSON.parse(event.newValue);
243
270
  console.log('oauth-success from storage');
244
271
  // Clean up
245
272
  localStorage.removeItem('oauth-success');
246
273
  window.removeEventListener('storage', handleStorageEvent);
274
+ if (data?.type === 'success') {
275
+ finishOauthFlow('storage');
276
+ }
277
+ else {
278
+ processPopupData(data);
279
+ }
247
280
  }
248
281
  catch (e) {
249
282
  console.error('Could not process oauth-success from storage', e);
@@ -253,11 +286,22 @@ function handleStorageEvent(event) {
253
286
  console.log('Storage event', event.key);
254
287
  }
255
288
  }
289
+ function finishOauthFlow(via, win) {
290
+ if (oauthFlowDone)
291
+ return;
292
+ oauthFlowDone = true;
293
+ console.log(`oauth: signaled via ${via}`);
294
+ if (win && !win.closed)
295
+ win.close();
296
+ window.removeEventListener('message', popupListener);
297
+ window.removeEventListener('storage', handleStorageEvent);
298
+ onLoginSuccess?.();
299
+ }
256
300
  onDestroy(() => {
257
301
  window.removeEventListener('message', popupListener);
258
302
  window.removeEventListener('storage', handleStorageEvent);
259
303
  });
260
- function storeRedirect(provider) {
304
+ function persistRd() {
261
305
  if (rd) {
262
306
  try {
263
307
  localStorage.setItem('rd', rd);
@@ -266,26 +310,86 @@ function storeRedirect(provider) {
266
310
  console.error('Could not persist redirection to local storage', e);
267
311
  }
268
312
  }
313
+ }
314
+ function storeRedirect(provider) {
315
+ persistRd();
269
316
  let url = base + '/api/oauth/login/' + provider + (popup ? '?close=true' : '');
270
317
  console.log('storeRedirect', popup, url);
271
318
  if (popup) {
272
319
  localStorage.setItem('closeUponLogin', 'true');
273
320
  window.addEventListener('message', popupListener);
274
321
  window.addEventListener('storage', handleStorageEvent);
275
- window.open(url, '_blank', 'popup');
322
+ const win = window.open(url, '_blank', 'popup');
323
+ if (!win) {
324
+ window.removeEventListener('message', popupListener);
325
+ window.removeEventListener('storage', handleStorageEvent);
326
+ return false;
327
+ }
328
+ // Safety net for Safari: when the popup is opened without a fresh user
329
+ // gesture (auto-login), ITP can partition cookies/localStorage between
330
+ // popup and parent, so neither the close cookie, the postMessage, nor
331
+ // the localStorage 'oauth-success' signal reaches us. The session
332
+ // cookie is set same-origin and isn't subject to that partitioning, so
333
+ // polling whoami catches the success and lets us force-close the popup.
334
+ pollForLoginSuccess(win);
335
+ return true;
276
336
  }
277
337
  else {
278
338
  localStorage.setItem('closeUponLogin', 'false');
279
339
  window.location.href = url;
340
+ return true;
280
341
  }
281
342
  }
343
+ function pollForLoginSuccess(win) {
344
+ const startedAt = Date.now();
345
+ const interval = setInterval(async () => {
346
+ if (oauthFlowDone) {
347
+ clearInterval(interval);
348
+ return;
349
+ }
350
+ if (Date.now() - startedAt > 5 * 60 * 1000) {
351
+ clearInterval(interval);
352
+ console.log('oauth: poll timed out after 5 minutes');
353
+ return;
354
+ }
355
+ if (win.closed) {
356
+ clearInterval(interval);
357
+ console.log('oauth: popup closed before login completed');
358
+ return;
359
+ }
360
+ try {
361
+ await UserService.getCurrentEmail();
362
+ }
363
+ catch {
364
+ return;
365
+ }
366
+ clearInterval(interval);
367
+ finishOauthFlow('poll', win);
368
+ }, 1500);
369
+ }
370
+ function redirectSaml() {
371
+ if (!saml) {
372
+ sendUserToast('No SAML login available', true);
373
+ return false;
374
+ }
375
+ persistRd();
376
+ window.location.href = saml;
377
+ return true;
378
+ }
282
379
  $effect(() => {
283
380
  error && sendUserToast(escapeHtml(error), true);
284
381
  });
285
382
  </script>
286
383
 
287
384
  <div class="bg-surface px-4 py-8 border sm:rounded-lg sm:px-10">
288
- <div class="grid {logins && logins.length > 2 ? 'grid-cols-2' : ''} gap-4">
385
+ {#if autoRedirecting}
386
+ <p class="text-sm text-center text-secondary py-4">Signing you in…</p>
387
+ {/if}
388
+ <div
389
+ class="grid {logins && logins.length > 2 ? 'grid-cols-2' : ''} gap-4 {autoRedirecting
390
+ ? 'hidden'
391
+ : ''}"
392
+ >
289
393
  {#if !logins}
290
394
  {#each Array(4) as _}
291
395
  <Skeleton layout={[0.5, [2.375]]} />
@@ -313,29 +417,10 @@ $effect(() => {
313
417
  {/each}
314
418
  {/if}
315
419
  {#if saml}
316
- <Button
317
- variant="default"
318
- btnClasses="mt-2 w-full"
319
- on:click={() => {
320
- if (saml) {
321
- if (rd) {
322
- try {
323
- localStorage.setItem('rd', rd)
324
- } catch (e) {
325
- console.error('Could not persist redirection to local storage', e)
326
- }
327
- }
328
- window.location.href = saml
329
- } else {
330
- sendUserToast('No SAML login available', true)
331
- }
332
- }}
333
- >
334
- SSO
335
- </Button>
420
+ <Button variant="default" btnClasses="mt-2 w-full" on:click={redirectSaml}>SSO</Button>
336
421
  {/if}
337
422
  </div>
338
- {#if !disablePasswordLogin && (saml || (logins && logins.length > 0))}
423
+ {#if !autoRedirecting && !disablePasswordLogin && (saml || (logins && logins.length > 0))}
339
424
  <div class={classNames('center-center', logins && logins.length > 0 ? 'mt-6' : '')}>
340
425
  <Button
341
426
  size="xs"
@@ -349,7 +434,7 @@ $effect(() => {
349
434
  </div>
350
435
  {/if}
351
436
 
352
- {#if showPassword && !disablePasswordLogin}
437
+ {#if !autoRedirecting && showPassword && !disablePasswordLogin}
353
438
  <div>
354
439
  {#if firstTime}
355
440
  <p class="text-xs text-center w-full pb-4 text-secondary">
@@ -5,6 +5,7 @@ interface Props {
5
5
  error?: string | undefined;
6
6
  popup?: boolean;
7
7
  firstTime?: boolean;
8
+ autoRedirect?: boolean;
8
9
  onLoginSuccess?: () => void;
9
10
  }
10
11
  declare const Login: import("svelte").Component<Props, {}, "email" | "password">;
@@ -4,7 +4,7 @@ const lastMetaUsed = writable(undefined);
4
4
 
5
5
  <script lang="ts">import { pathToMeta } from '../common';
6
6
  import { localeConcatAnd, pluralize } from '../utils';
7
- import { AppService, FlowService, FolderService, ResourceService, ScheduleService, ScriptService, HttpTriggerService, VariableService, WebsocketTriggerService, KafkaTriggerService, PostgresTriggerService, NatsTriggerService, MqttTriggerService, SqsTriggerService, GcpTriggerService, EmailTriggerService } from '../gen';
7
+ import { AppService, FlowService, FolderService, ResourceService, ScheduleService, ScriptService, HttpTriggerService, VariableService, WebsocketTriggerService, KafkaTriggerService, PostgresTriggerService, NatsTriggerService, MqttTriggerService, SqsTriggerService, GcpTriggerService, AzureTriggerService, EmailTriggerService } from '../gen';
8
8
  import { superadmin, userStore, workspaceStore } from '../stores';
9
9
  import { createEventDispatcher, getContext, untrack } from 'svelte';
10
10
  import { writable } from 'svelte/store';
@@ -226,6 +226,12 @@ async function pathExists(path, kind) {
226
226
  path: path
227
227
  });
228
228
  }
229
+ else if (kind === 'azure_trigger') {
230
+ return await AzureTriggerService.existsAzureTrigger({
231
+ workspace: $workspaceStore,
232
+ path: path
233
+ });
234
+ }
229
235
  else if (kind === 'email_trigger') {
230
236
  return await EmailTriggerService.existsEmailTrigger({
231
237
  workspace: $workspaceStore,
@@ -1,4 +1,4 @@
1
- type PathKind = 'resource' | 'script' | 'variable' | 'flow' | 'schedule' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'postgres_trigger' | 'nats_trigger' | 'mqtt_trigger' | 'sqs_trigger' | 'gcp_trigger' | 'email_trigger';
1
+ type PathKind = 'resource' | 'script' | 'variable' | 'flow' | 'schedule' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'postgres_trigger' | 'nats_trigger' | 'mqtt_trigger' | 'sqs_trigger' | 'gcp_trigger' | 'azure_trigger' | 'email_trigger';
2
2
  interface Props {
3
3
  fullNamePlaceholder?: string | undefined;
4
4
  namePlaceholder?: string;
@@ -218,7 +218,8 @@ async function cancelJobs(uuidsToCancel, forceCancel = false) {
218
218
  const uuids = await JobService.cancelSelection({
219
219
  workspace: $workspaceStore ?? '',
220
220
  requestBody: uuidsToCancel,
221
- forceCancel: forceCancel
221
+ forceCancel: forceCancel,
222
+ allWorkspaces: filters.val.all_workspaces || undefined
222
223
  });
223
224
  selectedIds = [];
224
225
  jobsLoader?.loadJobs(true, true);
@@ -567,53 +567,51 @@ $effect.pre(() => {
567
567
  {/if}
568
568
  </div>
569
569
  {:else}
570
- <div class="p-4 gap-2">
571
- <Section
572
- label={((p) => (p.startsWith(rootPath) ? p.slice(rootPath.length) : p))(
573
- fileMetadata.fileKey
574
- )}
575
- breakAll
576
- >
577
- {#snippet action()}
578
- <div class="flex gap-2">
579
- {#if filePreview !== undefined}
580
- {#if !hideS3SpecificDetails}
581
- <Button
582
- title="Download file from S3"
583
- variant="default"
584
- href={`${base}/api/w/${$workspaceStore}/job_helpers/download_s3_file?file_key=${encodeURIComponent(fileMetadata?.fileKey ?? '')}${storage ? `&storage=${storage}` : ''}`}
585
- download={fileMetadata?.fileKey.split('/').pop() ?? 'unnamed_download.file'}
586
- startIcon={{ icon: Download }}
587
- iconOnly={true}
588
- />
589
- {/if}
590
- {#if !readOnlyMode}
591
- <Button
592
- title="Move file"
593
- variant="default"
594
- on:click={() => {
595
- moveDestKey = fileMetadata?.fileKey ?? ''
596
- moveModalOpen = true
597
- }}
598
- startIcon={{ icon: MoveRight }}
599
- iconOnly={true}
600
- />
601
- {/if}
602
- {#if !readOnlyMode || allowDelete}
603
- <Button
604
- title="Delete file"
605
- variant="default"
606
- on:click={() => {
607
- deletionModalOpen = true
608
- }}
609
- startIcon={{ icon: Trash }}
610
- iconOnly={true}
611
- />
612
- {/if}
570
+ <div class="px-3 py-2 flex flex-col gap-2">
571
+ <div class="flex flex-row items-center justify-between gap-2">
572
+ <h2 class="text-emphasis text-sm font-semibold break-all min-w-0">
573
+ {((p) => (p.startsWith(rootPath) ? p.slice(rootPath.length) : p))(
574
+ fileMetadata.fileKey
575
+ )}
576
+ </h2>
577
+ {#if filePreview !== undefined && (!hideS3SpecificDetails || !readOnlyMode || allowDelete)}
578
+ <div class="flex gap-2 shrink-0">
579
+ {#if !hideS3SpecificDetails}
580
+ <Button
581
+ title="Download file from S3"
582
+ variant="default"
583
+ href={`${base}/api/w/${$workspaceStore}/job_helpers/download_s3_file?file_key=${encodeURIComponent(fileMetadata?.fileKey ?? '')}${storage ? `&storage=${storage}` : ''}`}
584
+ download={fileMetadata?.fileKey.split('/').pop() ?? 'unnamed_download.file'}
585
+ startIcon={{ icon: Download }}
586
+ iconOnly={true}
587
+ />
588
+ {/if}
589
+ {#if !readOnlyMode}
590
+ <Button
591
+ title="Move file"
592
+ variant="default"
593
+ on:click={() => {
594
+ moveDestKey = fileMetadata?.fileKey ?? ''
595
+ moveModalOpen = true
596
+ }}
597
+ startIcon={{ icon: MoveRight }}
598
+ iconOnly={true}
599
+ />
600
+ {/if}
601
+ {#if !readOnlyMode || allowDelete}
602
+ <Button
603
+ title="Delete file"
604
+ variant="default"
605
+ on:click={() => {
606
+ deletionModalOpen = true
607
+ }}
608
+ startIcon={{ icon: Trash }}
609
+ iconOnly={true}
610
+ />
613
611
  {/if}
614
612
  </div>
615
- {/snippet}
616
- </Section>
613
+ {/if}
614
+ </div>
617
615
  {#if !hideS3SpecificDetails}
618
616
  <TableSimple
619
617
  headers={['Last modified', 'Size', 'Type']}
@@ -652,51 +650,53 @@ $effect.pre(() => {
652
650
  <Loader2 size={12} class="animate-spin mr-1" /> File preview loading
653
651
  </div>
654
652
  {:else if fileMetadata !== undefined && filePreview !== undefined}
655
- <div class="flex items-center text-primary mb-4">
656
- {#if filePreview.contentType === 'Unknown'}
657
- Type of file not supported for preview.
658
- {:else if filePreview.contentType === 'Csv'}
659
- Previewing a {filePreview.contentType?.toLowerCase()} file. Separator character:
660
- <div class="inline-flex w-12 ml-2 mr-2">
661
- <select
662
- class="h-8"
663
- bind:value={csvSeparatorChar}
664
- onchange={(e) =>
665
- loadFilePreview(
666
- fileMetadata?.fileKey ?? '',
667
- fileMetadata?.size,
668
- fileMetadata?.mimeType
653
+ {#if filePreview.contentType === 'Unknown' || filePreview.contentType === 'Csv' || !hideS3SpecificDetails}
654
+ <div class="flex items-center text-primary mb-4">
655
+ {#if filePreview.contentType === 'Unknown'}
656
+ Type of file not supported for preview.
657
+ {:else if filePreview.contentType === 'Csv'}
658
+ Previewing a {filePreview.contentType?.toLowerCase()} file. Separator character:
659
+ <div class="inline-flex w-12 ml-2 mr-2">
660
+ <select
661
+ class="h-8"
662
+ bind:value={csvSeparatorChar}
663
+ onchange={(e) =>
664
+ loadFilePreview(
665
+ fileMetadata?.fileKey ?? '',
666
+ fileMetadata?.size,
667
+ fileMetadata?.mimeType
668
+ )}
669
+ >
670
+ <option value=",">,</option>
671
+ <option value=";">;</option>
672
+ <option value="\t">\t</option>
673
+ <option value="|">|</option>
674
+ </select>
675
+ </div>
676
+ Header row:
677
+ <div class="inline-flex item-center w-4 ml-2 mr-2">
678
+ <input
679
+ onfocus={bubble('focus')}
680
+ onclick={bubble('click')}
681
+ disabled={false}
682
+ type="checkbox"
683
+ id="csv-header"
684
+ class="h-5"
685
+ bind:checked={csvHasHeader}
686
+ onchange={stopPropagation((e) =>
687
+ loadFilePreview(
688
+ fileMetadata?.fileKey ?? '',
689
+ fileMetadata?.size,
690
+ fileMetadata?.mimeType
691
+ )
669
692
  )}
670
- >
671
- <option value=",">,</option>
672
- <option value=";">;</option>
673
- <option value="\t">\t</option>
674
- <option value="|">|</option>
675
- </select>
676
- </div>
677
- Header row:
678
- <div class="inline-flex item-center w-4 ml-2 mr-2">
679
- <input
680
- onfocus={bubble('focus')}
681
- onclick={bubble('click')}
682
- disabled={false}
683
- type="checkbox"
684
- id="csv-header"
685
- class="h-5"
686
- bind:checked={csvHasHeader}
687
- onchange={stopPropagation((e) =>
688
- loadFilePreview(
689
- fileMetadata?.fileKey ?? '',
690
- fileMetadata?.size,
691
- fileMetadata?.mimeType
692
- )
693
- )}
694
- />
695
- </div>
696
- {:else if !hideS3SpecificDetails}
697
- Previewing a {filePreview.contentType?.toLowerCase()} file.
698
- {/if}
699
- </div>
693
+ />
694
+ </div>
695
+ {:else}
696
+ Previewing a {filePreview.contentType?.toLowerCase()} file.
697
+ {/if}
698
+ </div>
699
+ {/if}
700
700
  <pre class="grow whitespace-no-wrap break-words"
701
701
  >{#if !emptyString(filePreview.contentPreview)}{filePreview.contentPreview}{:else if filePreview.contentType !== undefined}Preview impossible.{/if}
702
702
  </pre>
@@ -71,12 +71,18 @@ let testPanelArgs = $state({});
71
71
  let testPanelSchema = $state(emptySchema());
72
72
  // editorCode is what the editor shows; code always holds the main script content
73
73
  let editorCode = $state(code);
74
- // Sync editorCode when code changes externally (template reset, copilot, etc.)
74
+ // Sync editorCode when code changes externally (template reset, copilot,
75
+ // new-script template init, etc.). We also re-run schema inference in that
76
+ // case — otherwise if the code prop is set after ScriptEditor's onMount (as
77
+ // happens on /scripts/add when initContent sets script.content after the
78
+ // editor has already mounted with an empty string), the schema would stay
79
+ // empty until the user typed into the editor.
75
80
  let lastSyncedCode = code;
76
81
  $effect.pre(() => {
77
82
  if (activeModuleTab === null && code !== lastSyncedCode) {
78
83
  editorCode = code;
79
84
  lastSyncedCode = code;
85
+ untrack(() => inferSchema(code));
80
86
  }
81
87
  });
82
88
  function switchToModule(modulePath) {
@@ -372,8 +378,9 @@ watch(() => inferAssetsRes.current, () => {
372
378
  if (old?.alt_access_type)
373
379
  asset.alt_access_type = old.alt_access_type;
374
380
  }
375
- if (!deepEqual(assets, newAssets))
376
- assets = newAssets;
381
+ const normalizedAssets = newAssets.length > 0 ? newAssets : undefined;
382
+ if (!deepEqual(assets, normalizedAssets))
383
+ assets = normalizedAssets;
377
384
  });
378
385
  watch([() => code, () => lang], () => {
379
386
  if (lang !== 'ansible')
@@ -882,8 +889,14 @@ $effect(() => {
882
889
  monacoEditor.updateOptions({ glyphMargin: false });
883
890
  }
884
891
  });
885
- onMount(() => {
886
- inferSchema(code, { applyInitialArgs: true });
892
+ onMount(async () => {
893
+ await inferSchema(code, { applyInitialArgs: true });
894
+ // Retry once if the initial inference failed silently (e.g. transient WASM
895
+ // init race). Without this, users had to modify the code to trigger a
896
+ // second on:change-driven inference.
897
+ if (!validCode && code && lang) {
898
+ await inferSchema(code, { applyInitialArgs: true });
899
+ }
887
900
  loadPastTests();
888
901
  aiChatManager.saveAndClear();
889
902
  aiChatManager.changeMode(AIMode.SCRIPT);
@@ -16,7 +16,7 @@ declare const ShareModal: $$__sveltets_2_IsomorphicComponent<Record<string, neve
16
16
  } & {
17
17
  [evt: string]: CustomEvent<any>;
18
18
  }, {}, {
19
- openDrawer: (newPath: string, kind_l: "resource" | "volume" | "script" | "flow" | "app" | "variable" | "schedule" | "raw_app" | "group_" | "http_trigger" | "websocket_trigger" | "kafka_trigger" | "nats_trigger" | "postgres_trigger" | "mqtt_trigger" | "gcp_trigger" | "sqs_trigger" | "email_trigger", isOwnerOverride?: boolean) => Promise<void>;
19
+ openDrawer: (newPath: string, kind_l: "resource" | "volume" | "script" | "flow" | "app" | "variable" | "schedule" | "raw_app" | "group_" | "http_trigger" | "websocket_trigger" | "kafka_trigger" | "nats_trigger" | "postgres_trigger" | "mqtt_trigger" | "gcp_trigger" | "azure_trigger" | "sqs_trigger" | "email_trigger", isOwnerOverride?: boolean) => Promise<void>;
20
20
  }, "">;
21
21
  type ShareModal = InstanceType<typeof ShareModal>;
22
22
  export default ShareModal;
@@ -84,6 +84,7 @@ declare const RunnableComponent: $$__sveltets_2_IsomorphicComponent<Props, {
84
84
  path?: string;
85
85
  lock?: string;
86
86
  cache_ttl?: number;
87
+ tag?: string;
87
88
  };
88
89
  id?: number;
89
90
  force_viewer_static_fields?: {
@@ -93,6 +94,8 @@ declare const RunnableComponent: $$__sveltets_2_IsomorphicComponent<Props, {
93
94
  [key: string]: unknown;
94
95
  };
95
96
  force_viewer_allow_user_resources?: Array<(string)>;
97
+ force_viewer_sensitive_inputs?: Array<(string)>;
98
+ force_viewer_delete_after_secs?: number;
96
99
  run_query_params?: {
97
100
  [key: string]: unknown;
98
101
  };
@@ -16,7 +16,8 @@ export async function executeRunnable(runnable, workspace, version, username, pa
16
16
  language: inlineScript.language ?? '',
17
17
  path: appPath + '/' + id,
18
18
  lock: inlineScript.id === undefined ? inlineScript.lock : undefined,
19
- cache_ttl: inlineScript.cache_ttl
19
+ cache_ttl: inlineScript.cache_ttl,
20
+ ...(inlineScript.tag ? { tag: inlineScript.tag } : {})
20
21
  };
21
22
  }
22
23
  }
@@ -47,7 +47,7 @@ $effect(() => {
47
47
  });
48
48
  let isSlackConnectedWorkspace = $state(false);
49
49
  async function getWorspaceSlackSetting() {
50
- const settings = await WorkspaceService.getSettings({
50
+ const settings = await WorkspaceService.getPublicSettings({
51
51
  workspace: $workspaceStore
52
52
  });
53
53
  if (settings.slack_name) {
@@ -151,7 +151,8 @@ export async function processRunnable(id, runnable, fields, app) {
151
151
  {
152
152
  static_inputs: staticInputs,
153
153
  one_of_inputs: oneOfInputs,
154
- allow_user_resources: allowUserResources
154
+ allow_user_resources: allowUserResources,
155
+ ...(runnable.inlineScript?.tag ? { tag: runnable.inlineScript.tag } : {})
155
156
  }
156
157
  ];
157
158
  }
@@ -6,5 +6,8 @@ export type TriggerableV2 = {
6
6
  static_inputs: Record<string, any>;
7
7
  one_of_inputs?: Record<string, any[] | undefined>;
8
8
  allow_user_resources?: string[];
9
+ delete_after_secs?: number;
10
+ sensitive_inputs?: string[];
11
+ tag?: string;
9
12
  };
10
13
  export declare function hash(message: any): Promise<string>;
@@ -22,7 +22,7 @@ let { cache_ttl = $bindable(), btnProps } = $props();
22
22
  nonCaptureEvent={true}
23
23
  btnClasses={Boolean(cache_ttl)
24
24
  ? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600'
25
- : 'bg-surface text-primay hover:bg-hover'}
25
+ : 'bg-surface text-primary hover:bg-hover'}
26
26
  color="light"
27
27
  variant="contained"
28
28
  size="xs2"
@@ -16,6 +16,7 @@ import { scriptLangToEditorLang } from '../../../../scripts';
16
16
  import ScriptGen from '../../../copilot/ScriptGen.svelte';
17
17
  import DiffEditor from '../../../DiffEditor.svelte';
18
18
  import CacheTtlPopup from './CacheTtlPopup.svelte';
19
+ import TagPopup from './TagPopup.svelte';
19
20
  import EditorSettings from '../../../EditorSettings.svelte';
20
21
  import { userStore, workspaceStore } from '../../../../stores';
21
22
  import TextInput from '../../../text_input/TextInput.svelte';
@@ -187,6 +188,12 @@ let extraLib = $derived(isFrontend && worldStore
187
188
  {/if}
188
189
  <div class="flex w-full flex-row gap-1 items-center justify-end">
189
190
  {#if inlineScript}
191
+ {#if inlineScript.language != 'frontend'}
192
+ <TagPopup
193
+ bind:tag={inlineScript.tag}
194
+ btnProps={{ unifiedSize: 'sm', variant: 'subtle' }}
195
+ />
196
+ {/if}
190
197
  <CacheTtlPopup
191
198
  bind:cache_ttl={inlineScript.cache_ttl}
192
199
  btnProps={{ unifiedSize: 'sm', variant: 'subtle' }}