windmill-components 1.665.0 → 1.677.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 (254) 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/map/FlowModuleSchemaMap.svelte +49 -9
  161. package/package/components/flows/pickers/PickHubScriptQuick.svelte +5 -3
  162. package/package/components/flows/pickers/PickHubScriptQuick.svelte.d.ts +1 -1
  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/recording/ScriptRecordingReplay.svelte +0 -1
  196. package/package/components/resources/resourcesFilter.d.ts +15 -2
  197. package/package/components/resources/resourcesFilter.js +11 -2
  198. package/package/components/runs/JobDetailFieldConfig.js +5 -3
  199. package/package/components/runs/JobDetailHeader.svelte +5 -2
  200. package/package/components/runs/JobRunsPreview.svelte +1 -0
  201. package/package/components/runs/RunBadges.svelte +7 -4
  202. package/package/components/runs/RunRow.svelte +7 -7
  203. package/package/components/schedules/schedulesFilter.d.ts +15 -2
  204. package/package/components/schedules/schedulesFilter.js +11 -2
  205. package/package/components/schema/EditableSchemaWrapper.svelte +6 -8
  206. package/package/components/schema/PropertyEditor.svelte +22 -1
  207. package/package/components/schema/PropertyEditor.svelte.d.ts +1 -0
  208. package/package/components/schema/editable_schema_wrapper.d.ts +1 -0
  209. package/package/components/secretArgUtils.d.ts +7 -0
  210. package/package/components/secretArgUtils.js +45 -0
  211. package/package/components/settings/WorkspaceUserSettings.svelte +359 -286
  212. package/package/components/sidebar/OperatorMenu.svelte +215 -197
  213. package/package/components/triggers/CaptureWrapper.svelte +1 -1
  214. package/package/components/triggers/TriggerFilters.svelte +17 -5
  215. package/package/components/triggers/TriggerFilters.svelte.d.ts +2 -1
  216. package/package/components/triggers/kafka/KafkaCapture.svelte +6 -2
  217. package/package/components/triggers/kafka/KafkaCapture.svelte.d.ts +1 -1
  218. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +5 -1
  219. package/package/components/triggers/kafka/utils.js +1 -0
  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/forLater.js +4 -0
  232. package/package/gen/core/OpenAPI.js +1 -1
  233. package/package/gen/schemas.gen.d.ts +94 -294
  234. package/package/gen/schemas.gen.js +94 -294
  235. package/package/gen/services.gen.d.ts +5 -121
  236. package/package/gen/services.gen.js +5 -237
  237. package/package/gen/types.gen.d.ts +91 -715
  238. package/package/hubPaths.json +6 -3
  239. package/package/infer.d.ts +55 -0
  240. package/package/infer.js +131 -0
  241. package/package/infer.svelte.js +2 -0
  242. package/package/mcpEndpointTools.js +213 -22
  243. package/package/script_helpers.d.ts +3 -0
  244. package/package/script_helpers.js +26 -0
  245. package/package/scripts.d.ts +2 -1
  246. package/package/scripts.js +15 -3
  247. package/package/stores.d.ts +2 -0
  248. package/package/system_prompts/prompts.d.ts +6 -5
  249. package/package/system_prompts/prompts.js +188 -29
  250. package/package/user.js +5 -1
  251. package/package/utils.js +21 -0
  252. package/package/utils_deployable.d.ts +7 -0
  253. package/package/utils_workspace_deploy.js +36 -8
  254. package/package.json +6 -5
@@ -11,9 +11,9 @@ import Head from '../table/Head.svelte';
11
11
  import Toggle from '../Toggle.svelte';
12
12
  import Tooltip from '../Tooltip.svelte';
13
13
  import { UserService, WorkspaceService, GroupService } from '../../gen';
14
- import { userStore, workspaceStore, superadmin, globalEmailInvite } from '../../stores';
14
+ import { userStore, workspaceStore, superadmin, globalEmailInvite, enterpriseLicense } from '../../stores';
15
15
  import { sendUserToast } from '../../toast';
16
- import { Loader2, Mails, Search, Plus, UserMinus, X } from 'lucide-svelte';
16
+ import { Loader2, Mails, Search, Plus, UserMinus, X, Bot, LogIn } from 'lucide-svelte';
17
17
  import Select from '../select/Select.svelte';
18
18
  import SearchItems from '../SearchItems.svelte';
19
19
  import Cell from '../table/Cell.svelte';
@@ -38,6 +38,7 @@ let autoAddInstanceGroupsRoles = $state({});
38
38
  // Add new instance group form state
39
39
  let selectedNewInstanceGroup = $state(undefined);
40
40
  let selectedNewRole = $state('developer');
41
+ // Service account creation
41
42
  // Available groups for dropdowns - filter out already configured groups
42
43
  let availableGroupItems = $derived(instanceGroups
43
44
  .filter((group) => !autoAddInstanceGroups.includes(group.name))
@@ -326,6 +327,7 @@ const displayMode = $derived.by(() => {
326
327
  }
327
328
  return autoAdd ? 'add' : 'invite';
328
329
  });
330
+ const isAdminsWorkspaceWithoutEE = $derived($workspaceStore === 'admins' && !$enterpriseLicense);
329
331
  </script>
330
332
 
331
333
  <SearchItems
@@ -343,323 +345,341 @@ const displayMode = $derived.by(() => {
343
345
  link="https://www.windmill.dev/docs/core_concepts/roles_and_permissions"
344
346
  />
345
347
 
348
+ {#if isAdminsWorkspaceWithoutEE}
349
+ <Alert type="info" title="Admins workspace">
350
+ The admins workspace is reserved for superadmins. Only users with superadmin privileges can
351
+ access it. Members cannot be manually added or invited to this workspace.
352
+ </Alert>
353
+ {/if}
354
+
346
355
  <Section>
347
356
  {#snippet action()}
348
357
  <div class="flex flex-row items-center gap-2 relative whitespace-nowrap w-full">
349
358
  <input placeholder="Filter members" bind:value={userFilter} class="input !pl-8 !w-56" />
350
359
  <Search class="absolute left-2" size={14} />
351
360
 
352
- <Popover
353
- floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
354
- usePointerDownOutside
355
- >
356
- {#snippet trigger()}
357
- <Button
358
- variant="default"
359
- unifiedSize="md"
360
- nonCaptureEvent={true}
361
- startIcon={{ icon: Mails }}
362
- >Auto-{displayMode}: {autoInviteOrAddEnabled ? 'ON' : 'OFF'}
363
- </Button>
364
- {/snippet}
365
- {#snippet content()}
366
- <div class="flex flex-col items-start p-4 min-w-[320px] max-w-sm">
367
- {#if showAutoInviteToggle}
368
- <div class="text-xs mb-1 text-primary"
369
- >Mode <Tooltip>Whether to invite or add users directly to the workspace.</Tooltip>
370
- </div>
371
- <ToggleButtonGroup
372
- selected={displayMode}
373
- on:selected={async (e) => {
374
- const switchingToAdd = e.detail === 'add' && !autoAdd
361
+ {#if !isAdminsWorkspaceWithoutEE}
362
+ <Popover
363
+ floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
364
+ usePointerDownOutside
365
+ >
366
+ {#snippet trigger()}
367
+ <Button
368
+ variant="default"
369
+ unifiedSize="md"
370
+ nonCaptureEvent={true}
371
+ startIcon={{ icon: Mails }}
372
+ >Auto-{displayMode}: {autoInviteOrAddEnabled ? 'ON' : 'OFF'}
373
+ </Button>
374
+ {/snippet}
375
+ {#snippet content()}
376
+ <div class="flex flex-col items-start p-4 min-w-[320px] max-w-sm">
377
+ {#if showAutoInviteToggle}
378
+ <div class="text-xs mb-1 text-primary"
379
+ >Mode <Tooltip>Whether to invite or add users directly to the workspace.</Tooltip>
380
+ </div>
381
+ <ToggleButtonGroup
382
+ selected={displayMode}
383
+ on:selected={async (e) => {
384
+ const switchingToAdd = e.detail === 'add' && !autoAdd
375
385
 
376
- // If switching from invite to add on non-cloud, show confirmation with warning
377
- if (switchingToAdd && isLegacyAutoInvite) {
378
- switchToAutoAddConfirmCallback = async () => {
379
- autoAdd = true
386
+ // If switching from invite to add on non-cloud, show confirmation with warning
387
+ if (switchingToAdd && isLegacyAutoInvite) {
388
+ switchToAutoAddConfirmCallback = async () => {
389
+ autoAdd = true
390
+ if (autoInviteOrAddEnabled) {
391
+ await updateAutoInvite(true)
392
+ }
393
+ }
394
+ } else {
395
+ autoAdd = e.detail === 'add'
380
396
  if (autoInviteOrAddEnabled) {
381
397
  await updateAutoInvite(true)
382
398
  }
383
399
  }
384
- } else {
385
- autoAdd = e.detail === 'add'
386
- if (autoInviteOrAddEnabled) {
387
- await updateAutoInvite(true)
388
- }
400
+ }}
401
+ >
402
+ {#snippet children({ item })}
403
+ <ToggleButton value="invite" small label="Auto-invite" {item} />
404
+ <ToggleButton value="add" small label="Auto-add" {item} />
405
+ {/snippet}
406
+ </ToggleButtonGroup>
407
+
408
+ {#if isLegacyAutoInvite && !autoAdd}
409
+ <div class="mt-3 w-full">
410
+ <Alert type="warning" size="xs" title="Legacy mode">
411
+ Auto-invite is deprecated. Switching to auto-add will permanently disable
412
+ auto-invite for this workspace.
413
+ </Alert>
414
+ </div>
415
+ {/if}
416
+
417
+ <div class="mt-6"></div>
418
+ {/if}
419
+
420
+ <span class="text-xs mb-1">Role <Tooltip>Role of the auto-added users</Tooltip></span>
421
+ <ToggleButtonGroup
422
+ selected={operatorOnly ? 'operator' : 'developer'}
423
+ on:selected={async (e) => {
424
+ operatorOnly = e.detail === 'operator'
425
+ if (auto_invite_domain != undefined) {
426
+ await updateAutoInvite(true)
389
427
  }
390
428
  }}
391
429
  >
392
430
  {#snippet children({ item })}
393
- <ToggleButton value="invite" small label="Auto-invite" {item} />
394
- <ToggleButton value="add" small label="Auto-add" {item} />
431
+ <ToggleButton
432
+ value="operator"
433
+ small
434
+ label="Operator"
435
+ tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
436
+ {item}
437
+ />
438
+ <ToggleButton
439
+ value="developer"
440
+ small
441
+ label="Developer"
442
+ tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
443
+ {item}
444
+ />
395
445
  {/snippet}
396
446
  </ToggleButtonGroup>
397
447
 
398
- {#if isLegacyAutoInvite && !autoAdd}
399
- <div class="mt-3 w-full">
400
- <Alert type="warning" size="xs" title="Legacy mode">
401
- Auto-invite is deprecated. Switching to auto-add will permanently disable
402
- auto-invite for this workspace.
403
- </Alert>
404
- </div>
405
- {/if}
406
-
407
- <div class="mt-6"></div>
408
- {/if}
448
+ <div class="mt-6">
449
+ <Toggle
450
+ checked={autoInviteOrAddEnabled}
451
+ on:change={async (e) => {
452
+ const enabling = e.detail
409
453
 
410
- <span class="text-xs mb-1">Role <Tooltip>Role of the auto-added users</Tooltip></span>
411
- <ToggleButtonGroup
412
- selected={operatorOnly ? 'operator' : 'developer'}
413
- on:selected={async (e) => {
414
- operatorOnly = e.detail === 'operator'
415
- if (auto_invite_domain != undefined) {
416
- await updateAutoInvite(true)
417
- }
418
- }}
419
- >
420
- {#snippet children({ item })}
421
- <ToggleButton
422
- value="operator"
423
- label="Operator"
424
- tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
425
- {item}
426
- />
427
- <ToggleButton
428
- value="developer"
429
- label="Developer"
430
- tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
431
- {item}
432
- />
433
- {/snippet}
434
- </ToggleButtonGroup>
435
-
436
- <div class="mt-6">
437
- <Toggle
438
- checked={autoInviteOrAddEnabled}
439
- on:change={async (e) => {
440
- const enabling = e.detail
441
-
442
- if (enabling) {
443
- // Non-cloud users without legacy auto-invite: force auto-add mode
444
- if (!isCloudHosted() && !isLegacyAutoInvite) {
445
- autoAdd = true
446
- }
454
+ if (enabling) {
455
+ // Non-cloud users without legacy auto-invite: force auto-add mode
456
+ if (!isCloudHosted() && !isLegacyAutoInvite) {
457
+ autoAdd = true
458
+ }
447
459
 
448
- // Show confirmation when enabling auto-add
449
- if (autoAdd || (!isCloudHosted() && !showAutoInviteToggle)) {
450
- autoAddConfirmCallback = async () => {
460
+ // Show confirmation when enabling auto-add
461
+ if (autoAdd || (!isCloudHosted() && !showAutoInviteToggle)) {
462
+ autoAddConfirmCallback = async () => {
463
+ await updateAutoInvite(true)
464
+ }
465
+ } else {
451
466
  await updateAutoInvite(true)
452
467
  }
453
468
  } else {
454
- await updateAutoInvite(true)
455
- }
456
- } else {
457
- // Disabling: show confirmation if currently using auto-invite (legacy)
458
- if (isLegacyAutoInvite) {
459
- autoInviteDisableConfirmCallback = async () => {
469
+ // Disabling: show confirmation if currently using auto-invite (legacy)
470
+ if (isLegacyAutoInvite) {
471
+ autoInviteDisableConfirmCallback = async () => {
472
+ await updateAutoInvite(false)
473
+ }
474
+ } else {
460
475
  await updateAutoInvite(false)
461
476
  }
462
- } else {
463
- await updateAutoInvite(false)
464
477
  }
465
- }
466
- }}
467
- disabled={isCloudHosted() && !allowedAutoDomain}
468
- options={{
469
- right: isCloudHosted()
470
- ? `Auto-${displayMode} anyone from ${
471
- autoInviteOrAddEnabled ? auto_invite_domain : domain
472
- }`
473
- : `Auto-${displayMode} anyone joining the instance`
474
- }}
475
- />
478
+ }}
479
+ disabled={isCloudHosted() && !allowedAutoDomain}
480
+ options={{
481
+ right: isCloudHosted()
482
+ ? `Auto-${displayMode} anyone from ${
483
+ autoInviteOrAddEnabled ? auto_invite_domain : domain
484
+ }`
485
+ : `Auto-${displayMode} anyone joining the instance`
486
+ }}
487
+ />
488
+ </div>
489
+ {#if isCloudHosted() && !allowedAutoDomain}
490
+ <div class="text-red-400 text-xs">{domain} domain not allowed for auto-add</div>
491
+ {/if}
476
492
  </div>
477
- {#if isCloudHosted() && !allowedAutoDomain}
478
- <div class="text-red-400 text-xs">{domain} domain not allowed for auto-add</div>
479
- {/if}
480
- </div>
481
- {/snippet}
482
- </Popover>
483
-
484
- {#if instanceGroups.length > 0}
485
- <Popover
486
- floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
487
- usePointerDownOutside
488
- >
489
- {#snippet trigger()}
490
- <Button
491
- color={autoAddInstanceGroups.length > 0 ? 'green' : 'gray'}
492
- variant="border"
493
- size="xs"
494
- nonCaptureEvent={true}
495
- startIcon={{ icon: Mails }}
496
- >Instance groups: {autoAddInstanceGroups.length}
497
- </Button>
498
493
  {/snippet}
499
- {#snippet content()}
500
- <div class="flex flex-col p-4 min-w-[500px]">
501
- <div class="flex flex-col gap-4">
502
- <span class="text-sm leading-6 font-semibold"> Auto-add instance groups </span>
494
+ </Popover>
503
495
 
504
- <!-- Add new instance group form -->
505
- {#if availableGroupItems.length > 0}
506
- <div class="flex w-full mt-1 gap-2 items-end justify-between">
507
- <div class="flex gap-2 items-end">
508
- <div class="flex flex-col gap-1">
509
- <span class="text-xs text-primary">Instance group</span>
510
- <Select
511
- items={availableGroupItems}
512
- placeholder="Select group"
513
- bind:value={selectedNewInstanceGroup}
514
- class="max-w-[160px]"
515
- disablePortal={true}
516
- />
517
- </div>
496
+ {#if instanceGroups.length > 0}
497
+ <Popover
498
+ floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
499
+ usePointerDownOutside
500
+ >
501
+ {#snippet trigger()}
502
+ <Button
503
+ color={autoAddInstanceGroups.length > 0 ? 'green' : 'gray'}
504
+ variant="border"
505
+ size="xs"
506
+ nonCaptureEvent={true}
507
+ startIcon={{ icon: Mails }}
508
+ >Instance groups: {autoAddInstanceGroups.length}
509
+ </Button>
510
+ {/snippet}
511
+ {#snippet content()}
512
+ <div class="flex flex-col p-4 min-w-[500px]">
513
+ <div class="flex flex-col gap-4">
514
+ <span class="text-sm leading-6 font-semibold"> Auto-add instance groups </span>
518
515
 
519
- <div class="flex flex-col gap-1">
520
- <span class="text-xs text-primary">Role</span>
521
- <ToggleButtonGroup
522
- selected={selectedNewRole}
523
- on:selected={(e) => {
524
- selectedNewRole = e.detail
525
- }}
526
- >
527
- {#snippet children({ item })}
528
- <ToggleButton
529
- value="operator"
530
- label="Operator"
531
- tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
532
- {item}
533
- />
534
- <ToggleButton
535
- value="developer"
536
- label="Developer"
537
- tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
538
- {item}
539
- />
540
- <ToggleButton
541
- value="admin"
542
- label="Admin"
543
- tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
544
- {item}
545
- />
546
- {/snippet}
547
- </ToggleButtonGroup>
516
+ <!-- Add new instance group form -->
517
+ {#if availableGroupItems.length > 0}
518
+ <div class="flex w-full mt-1 gap-2 items-end justify-between">
519
+ <div class="flex gap-2 items-end">
520
+ <div class="flex flex-col gap-1">
521
+ <span class="text-xs text-primary">Instance group</span>
522
+ <Select
523
+ items={availableGroupItems}
524
+ placeholder="Select group"
525
+ bind:value={selectedNewInstanceGroup}
526
+ class="max-w-[160px]"
527
+ disablePortal={true}
528
+ />
529
+ </div>
530
+
531
+ <div class="flex flex-col gap-1">
532
+ <span class="text-xs text-primary">Role</span>
533
+ <ToggleButtonGroup
534
+ selected={selectedNewRole}
535
+ on:selected={(e) => {
536
+ selectedNewRole = e.detail
537
+ }}
538
+ >
539
+ {#snippet children({ item })}
540
+ <ToggleButton
541
+ value="operator"
542
+ small
543
+ label="Operator"
544
+ tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
545
+ {item}
546
+ />
547
+ <ToggleButton
548
+ value="developer"
549
+ small
550
+ label="Developer"
551
+ tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
552
+ {item}
553
+ />
554
+ <ToggleButton
555
+ value="admin"
556
+ small
557
+ label="Admin"
558
+ tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
559
+ {item}
560
+ />
561
+ {/snippet}
562
+ </ToggleButtonGroup>
563
+ </div>
548
564
  </div>
549
- </div>
550
565
 
551
- <Button
552
- color="blue"
553
- size="xs"
554
- startIcon={{ icon: Plus }}
555
- disabled={!selectedNewInstanceGroup || !selectedNewRole}
556
- onclick={addInstanceGroup}
557
- >
558
- Add
559
- </Button>
560
- </div>
561
- {/if}
566
+ <Button
567
+ color="blue"
568
+ size="xs"
569
+ startIcon={{ icon: Plus }}
570
+ disabled={!selectedNewInstanceGroup || !selectedNewRole}
571
+ onclick={addInstanceGroup}
572
+ >
573
+ Add
574
+ </Button>
575
+ </div>
576
+ {/if}
562
577
 
563
- <!-- Configured groups table -->
564
- {#if autoAddInstanceGroups.length > 0}
565
- <div class="flex flex-col gap-2">
566
- <p class="text-sm font-medium text-secondary">Configured groups:</p>
567
- <div class="flex flex-col gap-1">
568
- <table class="w-full text-sm">
569
- <thead>
570
- <tr class="text-left text-xs text-primary">
571
- <th class="pb-2 w-1/2">Group</th>
572
- <th class="pb-2 w-1/4">Role</th>
573
- <th class="pb-2 w-1/4"></th>
574
- </tr>
575
- </thead>
576
- <tbody>
577
- {#each autoAddInstanceGroups as groupName (groupName)}
578
- {@const group = instanceGroups.find((g) => g.name === groupName)}
579
- <tr class="border-t border-gray-200 dark:border-gray-700">
580
- <td class="py-2">
581
- <div class="font-medium">{groupName}</div>
582
- {#if group?.summary}
583
- <div class="text-xs text-primary">{group.summary}</div>
584
- {/if}
585
- </td>
586
- <td class="py-2">
587
- <div>
588
- <ToggleButtonGroup
589
- selected={autoAddInstanceGroupsRoles[groupName] || 'developer'}
590
- on:selected={async (e) => {
591
- autoAddInstanceGroupsRoles[groupName] = e.detail
592
- await updateGroupRole(groupName, e.detail)
593
- }}
594
- >
595
- {#snippet children({ item })}
596
- <ToggleButton
597
- value="operator"
598
- label="Operator"
599
- tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
600
- {item}
601
- />
602
- <ToggleButton
603
- value="developer"
604
- label="Developer"
605
- tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
606
- {item}
607
- />
608
- <ToggleButton
609
- value="admin"
610
- label="Admin"
611
- tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
612
- {item}
613
- />
614
- {/snippet}
615
- </ToggleButtonGroup>
616
- </div>
617
- </td>
618
- <td class="py-2">
619
- <div class="flex justify-end">
620
- <Button
621
- color="light"
622
- variant="contained"
623
- btnClasses="text-red-500"
624
- size="xs"
625
- spacingSize="xs2"
626
- onclick={() => {
627
- removeInstanceGroupConfirmedCallback = async () => {
628
- await removeInstanceGroup(groupName)
629
- }
630
- }}
631
- >
632
- Remove
633
- </Button>
634
- </div>
635
- </td>
578
+ <!-- Configured groups table -->
579
+ {#if autoAddInstanceGroups.length > 0}
580
+ <div class="flex flex-col gap-2">
581
+ <p class="text-sm font-medium text-secondary">Configured groups:</p>
582
+ <div class="flex flex-col gap-1">
583
+ <table class="w-full text-sm">
584
+ <thead>
585
+ <tr class="text-left text-xs text-primary">
586
+ <th class="pb-2 w-1/2">Group</th>
587
+ <th class="pb-2 w-1/4">Role</th>
588
+ <th class="pb-2 w-1/4"></th>
636
589
  </tr>
637
- {/each}
638
- </tbody>
639
- </table>
590
+ </thead>
591
+ <tbody>
592
+ {#each autoAddInstanceGroups as groupName (groupName)}
593
+ {@const group = instanceGroups.find((g) => g.name === groupName)}
594
+ <tr class="border-t border-gray-200 dark:border-gray-700">
595
+ <td class="py-2">
596
+ <div class="font-medium">{groupName}</div>
597
+ {#if group?.summary}
598
+ <div class="text-xs text-primary">{group.summary}</div>
599
+ {/if}
600
+ </td>
601
+ <td class="py-2">
602
+ <div>
603
+ <ToggleButtonGroup
604
+ selected={autoAddInstanceGroupsRoles[groupName] ||
605
+ 'developer'}
606
+ on:selected={async (e) => {
607
+ autoAddInstanceGroupsRoles[groupName] = e.detail
608
+ await updateGroupRole(groupName, e.detail)
609
+ }}
610
+ >
611
+ {#snippet children({ item })}
612
+ <ToggleButton
613
+ value="operator"
614
+ small
615
+ label="Operator"
616
+ tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
617
+ {item}
618
+ />
619
+ <ToggleButton
620
+ value="developer"
621
+ small
622
+ label="Developer"
623
+ tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
624
+ {item}
625
+ />
626
+ <ToggleButton
627
+ value="admin"
628
+ small
629
+ label="Admin"
630
+ tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
631
+ {item}
632
+ />
633
+ {/snippet}
634
+ </ToggleButtonGroup>
635
+ </div>
636
+ </td>
637
+ <td class="py-2">
638
+ <div class="flex justify-end">
639
+ <Button
640
+ color="light"
641
+ variant="contained"
642
+ btnClasses="text-red-500"
643
+ size="xs"
644
+ spacingSize="xs2"
645
+ onclick={() => {
646
+ removeInstanceGroupConfirmedCallback = async () => {
647
+ await removeInstanceGroup(groupName)
648
+ }
649
+ }}
650
+ >
651
+ Remove
652
+ </Button>
653
+ </div>
654
+ </td>
655
+ </tr>
656
+ {/each}
657
+ </tbody>
658
+ </table>
659
+ </div>
640
660
  </div>
641
- </div>
642
- {:else}
643
- <div class="text-center text-primary text-sm py-4">
644
- No instance groups configured for auto-add
645
- </div>
646
- {/if}
661
+ {:else}
662
+ <div class="text-center text-primary text-sm py-4">
663
+ No instance groups configured for auto-add
664
+ </div>
665
+ {/if}
666
+ </div>
647
667
  </div>
648
- </div>
649
- {/snippet}
650
- </Popover>
651
- {/if}
668
+ {/snippet}
669
+ </Popover>
670
+ {/if}
652
671
 
653
- {#if showAutoInviteToggle}
654
- <InviteUser {inviteUser} />
655
- {/if}
672
+ {#if showAutoInviteToggle}
673
+ <InviteUser {inviteUser} />
674
+ {/if}
656
675
 
657
- <AddUser
658
- on:new={() => {
659
- listUsers()
660
- listInvites()
661
- }}
662
- />
676
+ <AddUser
677
+ on:new={() => {
678
+ listUsers()
679
+ listInvites()
680
+ }}
681
+ />
682
+ {/if}
663
683
  </div>
664
684
  {/snippet}
665
685
 
@@ -711,8 +731,21 @@ const displayMode = $derived.by(() => {
711
731
  </tr>
712
732
  {/if}
713
733
  <tr class={index % 2 === 0 ? 'bg-surface-tertiary' : 'bg-surface'}>
714
- <Cell first><a href="mailto:{email}">{truncate(email, 20)}</a></Cell>
715
- <Cell>{truncate(username, 30)}</Cell>
734
+ <Cell first>
735
+ {#if user.is_service_account}
736
+ <span class="flex items-center gap-1.5 max-w-[150px]" title={email}>
737
+ <Bot size={16} class="text-blue-500 shrink-0" />
738
+ <span class="truncate">{email}</span>
739
+ </span>
740
+ {:else}
741
+ <a href="mailto:{email}" class="block truncate max-w-[150px]" title={email}
742
+ >{email}</a
743
+ >
744
+ {/if}
745
+ </Cell>
746
+ <Cell
747
+ ><span class="block truncate max-w-[120px]" title={username}>{username}</span></Cell
748
+ >
716
749
  {#if hasNonManualUsers}
717
750
  <Cell>
718
751
  <div class="flex items-center gap-2">
@@ -728,14 +761,21 @@ const displayMode = $derived.by(() => {
728
761
  </Cell>
729
762
  {/if}
730
763
  <Cell
731
- >{#if usage?.[email] != undefined}{usage?.[email]}{:else}<Loader2
764
+ >{#if usage != undefined}{usage[email] ?? 0}{:else}<Loader2
732
765
  size={14}
733
766
  class="animate-spin"
734
767
  />{/if}</Cell
735
768
  >
736
769
  <Cell>
737
770
  <div>
738
- {#if added_via?.source === 'instance_group'}
771
+ {#if user.is_service_account}
772
+ <div class="flex items-center gap-1">
773
+ <span class="rounded-md text-xs px-2 py-1 bg-surface shadow-md font-bold">
774
+ Operator
775
+ </span>
776
+ <Tooltip>Service accounts are always operators.</Tooltip>
777
+ </div>
778
+ {:else if added_via?.source === 'instance_group'}
739
779
  <div class="flex items-center gap-1">
740
780
  <span class="rounded-md text-xs px-2 py-1 bg-surface shadow-md font-bold">
741
781
  {is_admin ? 'Admin' : operator ? 'Operator' : 'Developer'}
@@ -772,6 +812,7 @@ const displayMode = $derived.by(() => {
772
812
  {#snippet children({ item })}
773
813
  <ToggleButton
774
814
  value="operator"
815
+ small
775
816
  label="Operator"
776
817
  tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
777
818
  {item}
@@ -779,6 +820,7 @@ const displayMode = $derived.by(() => {
779
820
 
780
821
  <ToggleButton
781
822
  value="developer"
823
+ small
782
824
  label="Developer"
783
825
  tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
784
826
  {item}
@@ -786,6 +828,7 @@ const displayMode = $derived.by(() => {
786
828
 
787
829
  <ToggleButton
788
830
  value="admin"
831
+ small
789
832
  label="Admin"
790
833
  tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
791
834
  {item}
@@ -819,6 +862,33 @@ const displayMode = $derived.by(() => {
819
862
  </Cell>
820
863
  <Cell>
821
864
  <div class="flex gap-1">
865
+ {#if user.is_service_account && $userStore?.is_admin}
866
+ <Button
867
+ unifiedSize="sm"
868
+ variant="default"
869
+ startIcon={{ icon: LogIn }}
870
+ disabled={!$enterpriseLicense}
871
+ title={!$enterpriseLicense ? 'Requires Enterprise Edition' : undefined}
872
+ onClick={async () => {
873
+ try {
874
+ // Backend sets the impersonation cookie and returns the old token
875
+ const oldToken = await UserService.impersonateServiceAccount({
876
+ workspace: $workspaceStore ?? '',
877
+ requestBody: { username }
878
+ })
879
+ if (oldToken) {
880
+ sessionStorage.setItem('pre_impersonation_token', oldToken)
881
+ sessionStorage.setItem('pre_impersonation_email', $userStore?.email ?? '')
882
+ }
883
+ window.location.href = '/'
884
+ } catch (e) {
885
+ sendUserToast('Failed to impersonate service account', true)
886
+ }
887
+ }}
888
+ >
889
+ Impersonate
890
+ </Button>
891
+ {/if}
822
892
  {#snippet removeUserButton(disabled: boolean)}
823
893
  <Button
824
894
  unifiedSize="sm"
@@ -894,7 +964,7 @@ const displayMode = $derived.by(() => {
894
964
  documentationLink="https://www.windmill.dev/docs/core_concepts/authentification#adding-users-to-a-workspace"
895
965
  >
896
966
  {#snippet action()}
897
- {#if showAutoInviteToggle}
967
+ {#if showAutoInviteToggle && !isAdminsWorkspaceWithoutEE}
898
968
  <div class="flex gap-2 items-center">
899
969
  <InviteUser {inviteUser} />
900
970
  </div>
@@ -937,6 +1007,7 @@ const displayMode = $derived.by(() => {
937
1007
  {#snippet children({ item })}
938
1008
  <ToggleButton
939
1009
  value="operator"
1010
+ small
940
1011
  label="Operator"
941
1012
  tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
942
1013
  {item}
@@ -944,6 +1015,7 @@ const displayMode = $derived.by(() => {
944
1015
 
945
1016
  <ToggleButton
946
1017
  value="developer"
1018
+ small
947
1019
  label="Developer"
948
1020
  tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
949
1021
  {item}
@@ -951,6 +1023,7 @@ const displayMode = $derived.by(() => {
951
1023
 
952
1024
  <ToggleButton
953
1025
  value="admin"
1026
+ small
954
1027
  label="Admin"
955
1028
  tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
956
1029
  {item}