mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
fix(core): Make workflow preview refresh after setup completes (no-changelog) (#28468)
Some checks failed
CI: Master (Build, Test, Lint) / Build for Github Cache (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (22.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.14.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (25.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Performance (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Build: Benchmark Image / build (push) Has been cancelled
Util: Sync API Docs / sync-public-api (push) Has been cancelled
Some checks failed
CI: Master (Build, Test, Lint) / Build for Github Cache (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (22.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.14.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (25.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Performance (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Build: Benchmark Image / build (push) Has been cancelled
Util: Sync API Docs / sync-public-api (push) Has been cancelled
This commit is contained in:
parent
fa3299d042
commit
e849041c11
|
|
@ -215,6 +215,19 @@ watch(
|
|||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.mode,
|
||||
() => {
|
||||
if (showPreview.value) {
|
||||
if (props.mode === 'workflow') {
|
||||
loadWorkflow();
|
||||
} else if (props.mode === 'execution') {
|
||||
loadExecution();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.executionId,
|
||||
() => {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ export interface BuildResult {
|
|||
toolCallId: string;
|
||||
}
|
||||
|
||||
export interface WorkflowSetupResult {
|
||||
workflowId: string;
|
||||
/** Unique per operation — changes even when the same workflow is set up again. */
|
||||
toolCallId: string;
|
||||
}
|
||||
|
||||
export interface DataTableResult {
|
||||
dataTableId: string;
|
||||
/** Unique per operation — changes even when the same table is modified again. */
|
||||
|
|
@ -45,6 +51,39 @@ export function getLatestBuildResult(node: InstanceAiAgentNode): BuildResult | u
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const WORKFLOW_SETUP_TOOLS = new Set(['setup-workflow', 'apply-workflow-credentials']);
|
||||
|
||||
/**
|
||||
* Walks an agent tree depth-first (most recent last) and returns the workflowId
|
||||
* (from args) and toolCallId from the latest successful setup-workflow /
|
||||
* apply-workflow-credentials tool result. These tools modify the workflow
|
||||
* (credentials, parameters) but don't return workflowId in the result.
|
||||
*/
|
||||
export function getLatestWorkflowSetupResult(
|
||||
node: InstanceAiAgentNode,
|
||||
): WorkflowSetupResult | undefined {
|
||||
for (let i = node.children.length - 1; i >= 0; i--) {
|
||||
const childResult = getLatestWorkflowSetupResult(node.children[i]);
|
||||
if (childResult) return childResult;
|
||||
}
|
||||
for (let i = node.toolCalls.length - 1; i >= 0; i--) {
|
||||
const tc = node.toolCalls[i];
|
||||
if (
|
||||
WORKFLOW_SETUP_TOOLS.has(tc.toolName) &&
|
||||
!tc.isLoading &&
|
||||
tc.result &&
|
||||
typeof tc.result === 'object'
|
||||
) {
|
||||
const result = tc.result as Record<string, unknown>;
|
||||
const args = tc.args as Record<string, unknown> | undefined;
|
||||
if (result.success === true && typeof args?.workflowId === 'string') {
|
||||
return { workflowId: args.workflowId, toolCallId: tc.toolCallId };
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface LatestExecution {
|
||||
executionId: string;
|
||||
workflowId: string;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
|
|||
import type { IconName } from '@n8n/design-system';
|
||||
import {
|
||||
getLatestBuildResult,
|
||||
getLatestWorkflowSetupResult,
|
||||
getLatestExecutionId,
|
||||
getLatestDataTableResult,
|
||||
getLatestDeletedDataTableId,
|
||||
|
|
@ -285,6 +286,35 @@ export function useCanvasPreview({ store, route, workflowExecutions }: UseCanvas
|
|||
},
|
||||
);
|
||||
|
||||
// --- Refresh preview when setup-workflow / apply-workflow-credentials completes ---
|
||||
// These tools modify the workflow (credentials, parameters) but aren't detected
|
||||
// by getLatestBuildResult. Refresh the preview so the iframe shows the latest state.
|
||||
|
||||
const latestSetupResult = computed(() => {
|
||||
for (let i = store.messages.length - 1; i >= 0; i--) {
|
||||
const msg = store.messages[i];
|
||||
if (msg.agentTree) {
|
||||
const result = getLatestWorkflowSetupResult(msg.agentTree);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => latestSetupResult.value?.toolCallId,
|
||||
(toolCallId) => {
|
||||
if (!toolCallId || !latestSetupResult.value) return;
|
||||
|
||||
const targetId = latestSetupResult.value.workflowId;
|
||||
|
||||
// Only refresh if the setup targeted the currently active workflow tab
|
||||
if (activeTabId.value === targetId) {
|
||||
workflowRefreshKey.value++;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// --- Auto-show execution after run-workflow completes ---
|
||||
|
||||
const latestExecution = computed(() => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user