refactor(editor): Introduce setter facades for workflow execution state (no-changelog) (#29675)

This commit is contained in:
Alex Grozav
2026-05-04 11:46:38 +00:00
committed by GitHub
parent 62ddc5c443
commit d422d2bafb
22 changed files with 173 additions and 112 deletions
@@ -41,7 +41,7 @@ describe('AiGatewaySelector', () => {
const pinia = createTestingPinia({ stubActions: false });
setActivePinia(pinia);
workflowsStore = mockedStore(useWorkflowsStore);
workflowsStore.workflowExecutionData = null;
workflowsStore.setWorkflowExecutionData(null);
});
describe('rendering', () => {
@@ -162,7 +162,7 @@ describe('AiGatewaySelector', () => {
renderComponent({ props: { aiGatewayEnabled: true, readonly: false } });
mockFetchBalance.mockClear();
workflowsStore.workflowExecutionData = { finished: true } as never;
workflowsStore.setWorkflowExecutionData({ finished: true } as never);
await vi.waitFor(() => expect(mockFetchBalance).toHaveBeenCalledOnce());
});
@@ -171,7 +171,7 @@ describe('AiGatewaySelector', () => {
renderComponent({ props: { aiGatewayEnabled: true, readonly: false } });
mockFetchBalance.mockClear();
workflowsStore.workflowExecutionData = { finished: false, stoppedAt: new Date() } as never;
workflowsStore.setWorkflowExecutionData({ finished: false, stoppedAt: new Date() } as never);
await vi.waitFor(() => expect(mockFetchBalance).toHaveBeenCalledOnce());
});
@@ -180,7 +180,7 @@ describe('AiGatewaySelector', () => {
renderComponent({ props: { aiGatewayEnabled: true, readonly: false } });
mockFetchBalance.mockClear();
workflowsStore.workflowExecutionData = { finished: false, stoppedAt: undefined } as never;
workflowsStore.setWorkflowExecutionData({ finished: false, stoppedAt: undefined } as never);
await new Promise((r) => setTimeout(r, 10));
expect(mockFetchBalance).not.toHaveBeenCalled();
@@ -190,17 +190,17 @@ describe('AiGatewaySelector', () => {
renderComponent({ props: { aiGatewayEnabled: true, readonly: false } });
mockFetchBalance.mockClear();
workflowsStore.workflowExecutionData = { finished: true } as never;
workflowsStore.setWorkflowExecutionData({ finished: true } as never);
await vi.waitFor(() => expect(mockFetchBalance).toHaveBeenCalledTimes(1));
workflowsStore.workflowExecutionData = { finished: true } as never;
workflowsStore.setWorkflowExecutionData({ finished: true } as never);
await vi.waitFor(() => expect(mockFetchBalance).toHaveBeenCalledTimes(2));
});
it('should not call fetchWallet when execution finishes but gateway is disabled', async () => {
renderComponent({ props: { aiGatewayEnabled: false, readonly: false } });
workflowsStore.workflowExecutionData = { finished: true } as never;
workflowsStore.setWorkflowExecutionData({ finished: true } as never);
await new Promise((r) => setTimeout(r, 10));
expect(mockFetchBalance).not.toHaveBeenCalled();
@@ -3923,6 +3923,12 @@ describe('useCanvasOperations', () => {
workflowsStore.removeTestWebhook = vi.fn();
workflowsStore.resetWorkflow = vi.fn();
workflowsStore.resetState = vi.fn();
workflowsStore.clearCurrentWorkflowExecutions = vi.fn(() => {
workflowsStore.currentWorkflowExecutions = [];
});
workflowsStore.setLastSuccessfulExecution = vi.fn((value) => {
workflowsStore.lastSuccessfulExecution = value;
});
const setActiveExecutionId = vi.spyOn(workflowState, 'setActiveExecutionId');
uiStore.resetLastInteractedWith = vi.fn();
executionsStore.activeExecution = null;
@@ -2316,9 +2316,9 @@ export function useCanvasOperations() {
// Reset editable workflow state
workflowsStore.resetWorkflow();
workflowState.resetState();
workflowsStore.currentWorkflowExecutions = [];
workflowsStore.clearCurrentWorkflowExecutions();
workflowState.setActiveExecutionId(undefined);
workflowsStore.lastSuccessfulExecution = null;
workflowsStore.setLastSuccessfulExecution(null);
// Reset actions
uiStore.resetLastInteractedWith();
@@ -3157,7 +3157,7 @@ export function useCanvasOperations() {
canvasStore.startLoading();
canvasStore.setLoadingText(i18n.baseText('nodeView.loadingTemplate'));
workflowsStore.currentWorkflowExecutions = [];
workflowsStore.clearCurrentWorkflowExecutions();
executionsStore.activeExecution = null;
let data: IWorkflowTemplate | undefined;
@@ -3220,7 +3220,7 @@ export function useCanvasOperations() {
canvasStore.startLoading();
canvasStore.setLoadingText(i18n.baseText('nodeView.loadingTemplate'));
workflowsStore.currentWorkflowExecutions = [];
workflowsStore.clearCurrentWorkflowExecutions();
executionsStore.activeExecution = null;
uiStore.isBlankRedirect = true;
@@ -45,7 +45,7 @@ describe('executionStarted', () => {
it('should accept execution when activeExecutionId is null and populate workflowData from store', async () => {
workflowsStore.activeExecutionId = null;
workflowsStore.workflowExecutionData = null;
workflowsStore.setWorkflowExecutionData(null);
workflowsStore.workflow.id = 'wf-123';
const workflowDocumentStore = useWorkflowDocumentStore(createWorkflowDocumentId('wf-123'));
workflowDocumentStore.setName('My Workflow');
@@ -64,10 +64,10 @@ describe('executionStarted', () => {
it('should not reinitialize when same execution ID arrives', async () => {
workflowsStore.activeExecutionId = 'exec-1';
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: 'exec-1',
data: { resultData: { runData: {} } },
} as never;
} as never);
await executionStarted(makeEvent('exec-1'), mockOptions);
@@ -97,10 +97,10 @@ describe('executionStarted', () => {
it('should accept execution when activeExecutionId is undefined in iframe (post-executionFinished)', async () => {
workflowsStore.activeExecutionId = undefined;
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: 'old-exec',
data: { resultData: { runData: { Node1: [{ executionTime: 100 }] } } },
} as never;
} as never);
await executionStarted(makeEvent('exec-2'), mockOptions);
@@ -112,10 +112,10 @@ describe('executionStarted', () => {
it('should accept new execution and reset state when re-executing in iframe', async () => {
workflowsStore.activeExecutionId = 'exec-1';
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: 'exec-1',
data: { resultData: { runData: { Node1: [{ executionTime: 100 }] } } },
} as never;
} as never);
await executionStarted(makeEvent('exec-2'), mockOptions);
@@ -127,10 +127,10 @@ describe('executionStarted', () => {
it('should not reset when same execution ID arrives in iframe', async () => {
workflowsStore.activeExecutionId = 'exec-1';
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: 'exec-1',
data: { resultData: { runData: {} } },
} as never;
} as never);
await executionStarted(makeEvent('exec-1'), mockOptions);
@@ -12,7 +12,7 @@ export async function testWebhookDeleted(
const workflowsStore = useWorkflowsStore();
if (data.workflowId === workflowsStore.workflowId) {
workflowsStore.executionWaitingForWebhook = false;
workflowsStore.setExecutionWaitingForWebhook(false);
options.workflowState.setActiveExecutionId(undefined);
}
}
@@ -12,7 +12,7 @@ export async function testWebhookReceived(
const workflowsStore = useWorkflowsStore();
if (data.workflowId === workflowsStore.workflowId) {
workflowsStore.executionWaitingForWebhook = false;
workflowsStore.setExecutionWaitingForWebhook(false);
options.workflowState.setActiveExecutionId(data.executionId ?? null);
}
}
@@ -100,6 +100,7 @@ vi.mock('@/app/stores/workflows.store', () => {
activeExecutionId: undefined,
previousExecutionId: undefined,
executionWaitingForWebhook: false,
chatPartialExecutionDestinationNode: null,
workflow: {
nodes: [],
id: '',
@@ -117,6 +118,16 @@ vi.mock('@/app/stores/workflows.store', () => {
'123': true,
},
getExecution: vi.fn(),
setWorkflowExecutionData: vi.fn((execution) => {
storeState.workflowExecutionData = execution;
}),
setExecutionWaitingForWebhook: vi.fn((value) => {
storeState.executionWaitingForWebhook = value;
}),
setChatPartialExecutionDestinationNode: vi.fn((value) => {
storeState.chatPartialExecutionDestinationNode = value;
}),
clearExecutionStartedData: vi.fn(),
private: {
setActiveExecutionId: vi.fn((id: string | null | undefined) => {
storeState.activeExecutionId = id;
@@ -1231,7 +1242,7 @@ describe('useRunWorkflow({ router })', () => {
'test-wf-id',
);
workflowState.setActiveExecutionId('test-exec-id');
workflowsStore.executionWaitingForWebhook = false;
workflowsStore.setExecutionWaitingForWebhook(false);
getExecutionSpy.mockResolvedValue(executionData);
@@ -134,7 +134,7 @@ export function useRunWorkflow(useRunWorkflowOpts: {
}
if (response.waitingForWebhook === true) {
workflowsStore.executionWaitingForWebhook = true;
workflowsStore.setExecutionWaitingForWebhook(true);
}
return response;
@@ -250,7 +250,7 @@ export function useRunWorkflow(useRunWorkflowOpts: {
// If the chat node has no input data or pin data, open the chat modal
// and halt the execution
if (!chatHasInputData && !chatHasPinData) {
workflowsStore.chatPartialExecutionDestinationNode = options.destinationNode.nodeName;
workflowsStore.setChatPartialExecutionDestinationNode(options.destinationNode.nodeName);
startChat();
return;
}
@@ -184,7 +184,7 @@ export function useWorkflowInitialization(workflowState: WorkflowState) {
const executionId = route.params.executionId;
if (typeof executionId === 'string') {
await applyExecutionData(executionId);
workflowsStore.isInDebugMode = true;
workflowsStore.setIsInDebugMode(true);
}
}
}
@@ -16,26 +16,28 @@ describe('useWorkflowState', () => {
describe('markExecutionAsStopped', () => {
beforeEach(() => {
workflowsStore.workflowExecutionData = createTestWorkflowExecutionResponse({
status: 'running',
startedAt: new Date('2023-01-01T09:00:00Z'),
stoppedAt: undefined,
data: createRunExecutionData({
resultData: {
runData: {
node1: [
createTestTaskData({ executionStatus: 'success' }),
createTestTaskData({ executionStatus: 'error' }),
createTestTaskData({ executionStatus: 'running' }),
],
node2: [
createTestTaskData({ executionStatus: 'success' }),
createTestTaskData({ executionStatus: 'waiting' }),
],
workflowsStore.setWorkflowExecutionData(
createTestWorkflowExecutionResponse({
status: 'running',
startedAt: new Date('2023-01-01T09:00:00Z'),
stoppedAt: undefined,
data: createRunExecutionData({
resultData: {
runData: {
node1: [
createTestTaskData({ executionStatus: 'success' }),
createTestTaskData({ executionStatus: 'error' }),
createTestTaskData({ executionStatus: 'running' }),
],
node2: [
createTestTaskData({ executionStatus: 'success' }),
createTestTaskData({ executionStatus: 'waiting' }),
],
},
},
},
}),
}),
});
);
});
it('should remove non successful node runs', () => {
@@ -7,7 +7,6 @@ import {
import { DEFAULT_SETTINGS } from '@/app/stores/workflowDocument/useWorkflowDocumentSettings';
import { useWorkflowsStore } from '@/app/stores/workflows.store';
import { useWorkflowStateStore } from '@/app/stores/workflowState.store';
import { getPairedItemsMapping } from '@/app/utils/pairedItemUtils';
import { isEmpty } from '@/app/utils/typesUtils';
import { useBuilderStore } from '@/features/ai/assistant/builder.store';
import type {
@@ -31,15 +30,7 @@ export function useWorkflowState() {
////
function setWorkflowExecutionData(workflowResultData: IExecutionResponse | null) {
if (workflowResultData?.data?.waitTill) {
delete workflowResultData.data.resultData.runData[
workflowResultData.data.resultData.lastNodeExecuted as string
];
}
ws.workflowExecutionData = workflowResultData;
ws.workflowExecutionPairedItemMappings = getPairedItemsMapping(workflowResultData);
ws.workflowExecutionResultDataLastUpdate = Date.now();
ws.workflowExecutionStartedData = undefined;
ws.setWorkflowExecutionData(workflowResultData);
}
function setActiveExecutionId(id: string | null | undefined) {
@@ -83,10 +74,10 @@ export function useWorkflowState() {
function markExecutionAsStopped(stopData?: IExecutionsStopData) {
setActiveExecutionId(undefined);
workflowStateStore.executingNode.clearNodeExecutionQueue();
ws.executionWaitingForWebhook = false;
ws.setExecutionWaitingForWebhook(false);
const workflowDocumentStore = useWorkflowDocumentStore(createWorkflowDocumentId(ws.workflowId));
documentTitle.setDocumentTitle(workflowDocumentStore.name, 'IDLE');
ws.workflowExecutionStartedData = undefined;
ws.clearExecutionStartedData();
// TODO(ckolb): confirm this works across files?
clearPopupWindowState();
@@ -115,7 +106,7 @@ export function useWorkflowState() {
setActiveExecutionId(undefined);
workflowStateStore.executingNode.executingNode.length = 0;
ws.executionWaitingForWebhook = false;
ws.setExecutionWaitingForWebhook(false);
useBuilderStore().resetManualExecutionStats();
}
@@ -219,14 +219,14 @@ describe('useWorkflowsStore', () => {
describe('getWorkflowRunData', () => {
it('should return null when no execution data is present', () => {
workflowsStore.workflowExecutionData = null;
workflowsStore.setWorkflowExecutionData(null);
const runData = workflowsStore.getWorkflowRunData;
expect(runData).toBeNull();
});
it('should return null when execution data does not contain resultData', () => {
workflowsStore.workflowExecutionData = { data: {} } as IExecutionResponse;
workflowsStore.setWorkflowExecutionData({ data: {} } as IExecutionResponse);
const runData = workflowsStore.getWorkflowRunData;
expect(runData).toBeNull();
@@ -234,9 +234,9 @@ describe('useWorkflowsStore', () => {
it('should return runData when execution data contains resultData', () => {
const expectedRunData = { node1: [{}, {}], node2: [{}] };
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
data: { resultData: { runData: expectedRunData } },
} as unknown as IExecutionResponse;
} as unknown as IExecutionResponse);
const runData = workflowsStore.getWorkflowRunData;
expect(runData).toEqual(expectedRunData);
@@ -245,16 +245,16 @@ describe('useWorkflowsStore', () => {
describe('getWorkflowResultDataByNodeName()', () => {
it('should return null when no workflow run data is present', () => {
workflowsStore.workflowExecutionData = null;
workflowsStore.setWorkflowExecutionData(null);
const resultData = workflowsStore.getWorkflowResultDataByNodeName('Node1');
expect(resultData).toBeNull();
});
it('should return null when node name is not present in workflow run data', () => {
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
data: { resultData: { runData: {} } },
} as unknown as IExecutionResponse;
} as unknown as IExecutionResponse);
const resultData = workflowsStore.getWorkflowResultDataByNodeName('Node1');
expect(resultData).toBeNull();
@@ -262,9 +262,9 @@ describe('useWorkflowsStore', () => {
it('should return result data when node name is present in workflow run data', () => {
const expectedData = [{}, {}];
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
data: { resultData: { runData: { Node1: expectedData } } },
} as unknown as IExecutionResponse;
} as unknown as IExecutionResponse);
const resultData = workflowsStore.getWorkflowResultDataByNodeName('Node1');
expect(resultData).toEqual(expectedData);
@@ -601,32 +601,34 @@ describe('useWorkflowsStore', () => {
describe('updateNodeExecutionRunData', () => {
beforeEach(() => {
workflowsStore.workflowExecutionData = createTestWorkflowExecutionResponse({
id: 'test-execution',
data: createRunExecutionData({
resultData: {
runData: {
n0: [
createTestTaskData({
executionIndex: 0,
executionStatus: 'success',
executionTime: 33,
}),
createTestTaskData({
executionIndex: 1,
executionStatus: 'success',
executionTime: 44,
}),
createTestTaskData({
executionIndex: 2,
executionStatus: 'running',
executionTime: undefined,
}),
],
workflowsStore.setWorkflowExecutionData(
createTestWorkflowExecutionResponse({
id: 'test-execution',
data: createRunExecutionData({
resultData: {
runData: {
n0: [
createTestTaskData({
executionIndex: 0,
executionStatus: 'success',
executionTime: 33,
}),
createTestTaskData({
executionIndex: 1,
executionStatus: 'success',
executionTime: 44,
}),
createTestTaskData({
executionIndex: 2,
executionStatus: 'running',
executionTime: undefined,
}),
],
},
},
},
}),
}),
});
);
});
it('should replace run data at the matched index in the execution data', () => {
@@ -1176,7 +1178,7 @@ describe('useWorkflowsStore', () => {
const nodeName = 'Rename me';
const newName = 'Renamed';
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
data: {
resultData: {
runData: {
@@ -1255,7 +1257,7 @@ describe('useWorkflowsStore', () => {
lastNodeExecuted: 'Edit Fields',
},
},
} as unknown as IExecutionResponse;
} as unknown as IExecutionResponse);
workflowsStore.workflow.id = 'test-workflow-id';
@@ -1873,7 +1875,7 @@ describe('useWorkflowsStore', () => {
workflowsStore.workflow.nodes = [createTestNode({ name: nodeName, type: WAIT_NODE_TYPE })];
// Initialize execution data directly
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: executionId,
workflowData: createTestWorkflow(),
finished: false,
@@ -1882,7 +1884,7 @@ describe('useWorkflowsStore', () => {
createdAt: new Date(),
status: 'running',
data: createEmptyRunExecutionData(),
} as IExecutionResponse;
} as IExecutionResponse);
// Call updateNodeExecutionStatus with waiting status and metadata.resumeFormUrl
workflowsStore.updateNodeExecutionStatus({
@@ -1914,7 +1916,7 @@ describe('useWorkflowsStore', () => {
workflowsStore.workflow.nodes = [createTestNode({ name: nodeName, type: WAIT_NODE_TYPE })];
// Initialize execution data directly
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: executionId,
workflowData: createTestWorkflow(),
finished: false,
@@ -1923,7 +1925,7 @@ describe('useWorkflowsStore', () => {
createdAt: new Date(),
status: 'running',
data: createEmptyRunExecutionData(),
} as IExecutionResponse;
} as IExecutionResponse);
// Call updateNodeExecutionStatus with waiting status but NO metadata.resumeFormUrl
workflowsStore.updateNodeExecutionStatus({
@@ -64,6 +64,7 @@ import {
createWorkflowDocumentId,
} from '@/app/stores/workflowDocument.store';
import { DEFAULT_SETTINGS } from '@/app/stores/workflowDocument/useWorkflowDocumentSettings';
import { getPairedItemsMapping } from '@/app/utils/pairedItemUtils';
const createEmptyWorkflow = (): IWorkflowDb => ({
id: '',
@@ -524,6 +525,46 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
}
}
function setWorkflowExecutionData(execution: IExecutionResponse | null): void {
if (execution?.data?.waitTill) {
delete execution.data.resultData.runData[
execution.data.resultData.lastNodeExecuted as string
];
}
workflowExecutionData.value = execution;
workflowExecutionPairedItemMappings.value = getPairedItemsMapping(execution);
workflowExecutionResultDataLastUpdate.value = Date.now();
workflowExecutionStartedData.value = undefined;
}
function clearExecutionStartedData(): void {
workflowExecutionStartedData.value = undefined;
}
function setExecutionWaitingForWebhook(value: boolean): void {
executionWaitingForWebhook.value = value;
}
function setIsInDebugMode(value: boolean): void {
isInDebugMode.value = value;
}
function setChatPartialExecutionDestinationNode(value: string | null): void {
chatPartialExecutionDestinationNode.value = value;
}
function setLastSuccessfulExecution(execution: IExecutionResponse | null): void {
lastSuccessfulExecution.value = execution;
}
function clearCurrentWorkflowExecutions(): void {
currentWorkflowExecutions.value = [];
}
function setCurrentWorkflowExecutions(executions: ExecutionSummary[]): void {
currentWorkflowExecutions.value = executions;
}
function renameNodeSelectedAndExecution(nameData: { old: string; new: string }): void {
uiStore.markStateDirty();
@@ -1090,6 +1131,14 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
setWorkflowInactive,
getDuplicateCurrentWorkflowName,
setWorkflowExecutionRunData,
setWorkflowExecutionData,
clearExecutionStartedData,
setExecutionWaitingForWebhook,
setIsInDebugMode,
setChatPartialExecutionDestinationNode,
setLastSuccessfulExecution,
clearCurrentWorkflowExecutions,
setCurrentWorkflowExecutions,
renameNodeSelectedAndExecution,
updateNodeExecutionRunData,
updateNodeExecutionStatus,
@@ -177,7 +177,7 @@ describe('AI Builder store', () => {
workflowsStore.workflow.nodes = [];
workflowsStore.workflow.connections = {};
workflowsStore.nodesByName = {};
workflowsStore.workflowExecutionData = null;
workflowsStore.setWorkflowExecutionData(null);
workflowState = useWorkflowState();
vi.mocked(injectWorkflowState).mockReturnValue(workflowState);
@@ -567,7 +567,7 @@ export const useChatStore = defineStore(STORES.CHAT_HUB, () => {
createWorkflowDocumentId(workflowsStore.workflowId),
);
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: IN_PROGRESS_EXECUTION_ID,
finished: false,
mode: 'manual',
@@ -580,7 +580,7 @@ export const useChatStore = defineStore(STORES.CHAT_HUB, () => {
resultData: { runData: {} },
}),
workflowData: workflowDocumentStore.getSnapshot(),
};
});
// Signal canvas that an execution is pending (null = waiting for execution ID)
workflowsStore.private.setActiveExecutionId(null);
@@ -175,7 +175,7 @@ export const useExecutionDebugging = (providedWorkflowState?: WorkflowState) =>
event.stopPropagation();
return;
}
workflowsStore.isInDebugMode = false;
workflowsStore.setIsInDebugMode(false);
};
return {
@@ -396,7 +396,7 @@ describe('useChatState', () => {
});
it('should include destinationNode when set in workflowsStore', async () => {
workflowsStore.chatPartialExecutionDestinationNode = 'DestinationNode';
workflowsStore.setChatPartialExecutionDestinationNode('DestinationNode');
const chatState = useChatState(false);
await chatState.registerChatWebhook();
@@ -523,7 +523,7 @@ describe('useChatState', () => {
});
it('should clear partial execution destination node', () => {
workflowsStore.chatPartialExecutionDestinationNode = 'SomeNode';
workflowsStore.setChatPartialExecutionDestinationNode('SomeNode');
const chatState = useChatState(false);
chatState.refreshSession();
@@ -217,7 +217,7 @@ export function useChatState(
mode: 'inclusive',
};
// Clear after use so subsequent messages run full workflow
workflowsStore.chatPartialExecutionDestinationNode = null;
workflowsStore.setChatPartialExecutionDestinationNode(null);
}
const response = await runWorkflow(runWorkflowOptions);
@@ -337,7 +337,7 @@ export function useChatState(
logsStore.resetChatSessionId();
logsStore.resetMessages();
// Clear partial execution destination to allow full workflow execution
workflowsStore.chatPartialExecutionDestinationNode = null;
workflowsStore.setChatPartialExecutionDestinationNode(null);
if (logsStore.isOpen) {
chatEventBus.emit('focusInput');
@@ -111,7 +111,7 @@ export function useLogsExecutionData({ isEnabled, filter }: UseLogsExecutionData
workflowState.setWorkflowExecutionData(null);
nodeHelpers.updateNodesExecutionIssues();
// Clear partial execution destination to allow full workflow execution
workflowsStore.chatPartialExecutionDestinationNode = null;
workflowsStore.setChatPartialExecutionDestinationNode(null);
void workflowsStore.fetchLastSuccessfulExecution();
}
@@ -65,7 +65,7 @@ describe('TriggerPanel.vue', () => {
});
it('renders listening state for webhook node', () => {
workflowsStore.executionWaitingForWebhook = true;
workflowsStore.setExecutionWaitingForWebhook(true);
workflowsStore.executedNode = 'Webhook';
const { getByTestId } = renderComponent(TriggerPanel, {
props: { nodeName: 'Webhook' },
@@ -79,7 +79,7 @@ describe('TriggerPanel.vue', () => {
});
it('does not render listening state for other nodes', () => {
workflowsStore.executionWaitingForWebhook = true;
workflowsStore.setExecutionWaitingForWebhook(true);
workflowsStore.executedNode = 'OtherNode';
const { queryByTestId } = renderComponent(TriggerPanel, {
props: { nodeName: 'Webhook' },
@@ -93,7 +93,7 @@ describe('TriggerPanel.vue', () => {
});
it('renders listening state when executedNode is a child of the current node', () => {
workflowsStore.executionWaitingForWebhook = true;
workflowsStore.setExecutionWaitingForWebhook(true);
workflowsStore.executedNode = 'ChildNode';
vi.spyOn(workflowDocStore, 'getParentNodes').mockReturnValue(['Webhook']);
const { getByTestId } = renderComponent(TriggerPanel, {
@@ -108,7 +108,7 @@ describe('TriggerPanel.vue', () => {
});
it('does not render listening state when executedNode is not a child or current node', () => {
workflowsStore.executionWaitingForWebhook = true;
workflowsStore.setExecutionWaitingForWebhook(true);
workflowsStore.executedNode = 'UnrelatedNode';
const { queryByTestId } = renderComponent(TriggerPanel, {
props: { nodeName: 'Webhook' },
@@ -62,7 +62,7 @@ async function createPiniaWithActiveNode() {
workflowsStore.workflow = workflow;
const workflowDocumentStore = useWorkflowDocumentStore(createWorkflowDocumentId(workflow.id));
workflowDocumentStore.initPristineNodeMetadata(node.name);
workflowsStore.workflowExecutionData = {
workflowsStore.setWorkflowExecutionData({
id: '1',
finished: true,
mode: 'trigger',
@@ -120,7 +120,7 @@ async function createPiniaWithActiveNode() {
},
},
}),
};
});
ndvStore.setActiveNodeName(node.name, 'other');
@@ -91,7 +91,7 @@ describe('RunDataAi', () => {
beforeEach(() => {
setActivePinia(createTestingPinia({ stubActions: false }));
workflowsStore = useWorkflowsStore();
workflowsStore.workflowExecutionData = executionResponse;
workflowsStore.setWorkflowExecutionData(executionResponse);
});
it('should render the log that belong to given run index', async () => {