From 82a574a980df685079ffb46b2f6adbfd954a279b Mon Sep 17 00:00:00 2001 From: wendrul <53628737+wendrul@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:02:11 +0100 Subject: [PATCH] feat: change on behalf selector to allow picking any user + select value in target by default if possible (#8113) * Make modal for on behalf of selector * Auto-select target * Show name of selected OnBehalfOfSelector * Fix frontend check --- .../lib/components/CompareWorkspaces.svelte | 24 +- .../src/lib/components/DeployWorkspace.svelte | 24 +- .../lib/components/OnBehalfOfSelector.svelte | 225 ++++++++++++++---- 3 files changed, 197 insertions(+), 76 deletions(-) diff --git a/frontend/src/lib/components/CompareWorkspaces.svelte b/frontend/src/lib/components/CompareWorkspaces.svelte index 2358ef40ab..85e7f05143 100644 --- a/frontend/src/lib/components/CompareWorkspaces.svelte +++ b/frontend/src/lib/components/CompareWorkspaces.svelte @@ -40,7 +40,7 @@ import DiffDrawer from './DiffDrawer.svelte' import DeployWorkspaceDrawer from './DeployWorkspaceDrawer.svelte' import ParentWorkspaceProtectionAlert from './ParentWorkspaceProtectionAlert.svelte' - import { userStore, userWorkspaces, workspaceStore } from '$lib/stores' + import { userWorkspaces, workspaceStore } from '$lib/stores' import type { Kind } from '$lib/utils_deployable' import { deployItem, getItemValue, getOnBehalfOfEmail } from '$lib/utils_workspace_deploy' @@ -119,6 +119,8 @@ // Source workspace on_behalf_of emails (keyed by workspace/kind:path) let onBehalfOfInfo = $state>({}) let onBehalfOfChoice = $state>({}) + let customOnBehalfOfEmails = $state>({}) + let deployTargetWorkspace = $derived(mergeIntoParent ? parentWorkspaceId : currentWorkspaceId) function getItemKey(diff: WorkspaceItemDiff): string { return `${diff.kind}:${diff.path}` @@ -210,14 +212,9 @@ return onBehalfOfInfo[getWorkspacedKey(targetWorkspace, itemKey)] } - // Check if an item needs on_behalf_of selection (more than 1 unique option) + // Check if an item needs on_behalf_of selection function itemNeedsOnBehalfOfSelection(itemKey: string, kind: string): boolean { - return needsOnBehalfOfSelection( - kind, - getSourceEmail(itemKey), - getTargetEmail(itemKey), - $userStore?.email - ) + return needsOnBehalfOfSelection(kind, getSourceEmail(itemKey)) } // Check if all required on_behalf_of selections are made @@ -234,8 +231,8 @@ // Get the email to use for deployment based on user's choice function getOnBehalfOfEmailForDeploy(itemKey: string): string | undefined { const choice = onBehalfOfChoice[itemKey] - if (choice === 'source') return getSourceEmail(itemKey) if (choice === 'target') return getTargetEmail(itemKey) + if (choice === 'custom') return customOnBehalfOfEmails[itemKey] // 'me' or undefined = don't pass, backend will use deploying user's email return undefined } @@ -868,7 +865,6 @@ {#snippet itemActions(item)} {@const diff = item.diff as WorkspaceItemDiff} {@const key = item.key} - {@const sourceEmail = getSourceEmail(key)} {@const targetEmail = getTargetEmail(key)} {@const isConflict = diff.ahead > 0 && diff.behind > 0} {@const existsInBothWorkspaces = !( @@ -878,12 +874,16 @@ {#if itemNeedsOnBehalfOfSelection(key, diff.kind)} (onBehalfOfChoice[key] = choice)} + onSelect={(choice, email) => { + onBehalfOfChoice[key] = choice + if (email) customOnBehalfOfEmails[key] = email + }} kind={diff.kind} canPreserve={canPreserveOnBehalfOf} + customEmail={customOnBehalfOfEmails[key]} /> {/if} diff --git a/frontend/src/lib/components/DeployWorkspace.svelte b/frontend/src/lib/components/DeployWorkspace.svelte index c3ef4217fa..c5e289a85b 100644 --- a/frontend/src/lib/components/DeployWorkspace.svelte +++ b/frontend/src/lib/components/DeployWorkspace.svelte @@ -1,7 +1,7 @@ - + e.detail && loadUsers()}> - + + + {#if selectedDisplayName} + {selectedDisplayName} + {/if} + -
+
{label}
- - + + {targetUsername} + (target) + + {/if} + + +
+ + + +
+
+ {#if kind === 'trigger'} + Choose the user this trigger will be recorded as edited by in the target workspace. + {:else} + Choose the user this {kind} will run on behalf of in the target workspace. The selected + user's permissions will be used when executing. + {/if} + + Learn more + + +
+ + + +
+ {#each filteredUsers as user (user.email)} + + {:else} +
+ {#if !usersLoaded} + Loading users… + {:else} + No users found + {/if} +
+ {/each} +
+
+