fix(automations): preserve destination form save semantics

(cherry picked from commit a793b07c12)
This commit is contained in:
Neil
2026-08-31 23:37:45 -07:00
parent a8c67c6663
commit 4de344d4ee
3 changed files with 33 additions and 18 deletions
@@ -236,30 +236,28 @@ export async function createAutomationOnDestination(
export async function saveExistingAutomation(
context: AutomationSaveContext,
automationId: string,
currentAutomation: Automation | null,
updates: AutomationUpdateInput,
destination: AutomationDestination | undefined,
fallbackTarget: AutomationHostTarget | null,
rowKey: string | null
): Promise<AutomationDispatchResult<Automation>> {
if (!currentAutomation) {
return {
ok: false,
notice: {
message: translate(
'auto.components.automations.AutomationsPage.ownerChanged',
'This automation changed hosts. Refresh and try again.'
),
recovery: 'retry',
severity: 'owner'
}
}
}
return await dispatchAutomationUpdate(
context.destination.automationDispatchContext,
{ rowKey: rowKey ?? '', automationId: currentAutomation.id },
{ rowKey: rowKey ?? '', automationId },
updates,
() => updateAutomationForTarget(currentAutomation, updates, fallbackTarget),
() => {
if (!currentAutomation) {
throw new Error(
translate(
'auto.components.automations.AutomationsPage.ownerChanged',
'This automation changed hosts. Refresh and try again.'
)
)
}
return updateAutomationForTarget(currentAutomation, updates, fallbackTarget)
},
'save',
destination
)
@@ -232,6 +232,7 @@ export async function saveOrcaAutomation(
} else if (editingAutomationId !== null) {
saved = await saveExistingAutomation(
context,
editingAutomationId,
currentAutomation,
updates,
editDestination,
@@ -51,6 +51,7 @@ export function useAutomationsPageDestinationForm({
settings
} = store
const {
createOpen,
createTarget,
editingAutomationId,
editingRowKey,
@@ -58,6 +59,7 @@ export function useAutomationsPageDestinationForm({
setEditingHostStableKey,
setEditingDestination,
setDraft,
draft,
draftRef
} = local
const { visibleRows, hostCatalog, capturedAutomationOwners } = list
@@ -162,9 +164,23 @@ export function useAutomationsPageDestinationForm({
? editHostProjects
: editorProjects
: getAutomationCreateRepos(repos, { kind: 'local' })
// A destination change can strand the chosen project on another host; clear
// it so the draft/default-target effect can select a project the host owns.
useEffect(() => {
if (!createOpen || editingAutomationId !== null || createTarget !== 'orca') {
return
}
setDraft((current) =>
!current.projectId || editorProjects.some((project) => project.id === current.projectId)
? current
: { ...current, projectId: '', workspaceId: '', baseBranch: '' }
)
}, [createOpen, createTarget, editingAutomationId, editorProjects, setDraft])
const dialogWorktrees = useMemo(() => {
const candidates = worktreesByRepo[draftRef.current.projectId] ?? []
const project = dialogRepos.find((repo) => repo.id === draftRef.current.projectId)
const candidates = worktreesByRepo[draft.projectId] ?? []
const project = dialogRepos.find((repo) => repo.id === draft.projectId)
if (!project) {
return candidates
}
@@ -179,7 +195,7 @@ export function useAutomationsPageDestinationForm({
worktree.runtimeOwnerEnvironmentId === parsedHost.environmentId
)
})
}, [dialogRepos, draftRef, worktreesByRepo])
}, [dialogRepos, draft.projectId, worktreesByRepo])
const destinationForProject = useCallback(
(projectId: string, hostStableKey?: string | null): AutomationCreateDestination | null => {
const selectedEntry = hostStableKey