Skip to content

Filter Executions by executed node #16036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Alexandero89
Copy link

Introduced the ability to filter executions by specific nodes in both backend and frontend components.

Summary

This PR is a first draft and also serves as a Request for Comments (RFC).

  • I frequently need to see all executions where a specific node was executed.
  • Currently, there is no way to filter executions by executed nodes.
  • This PR adds a button to the right-click context menu in the editor, enabling quick access to this functionality.
  • It introduces an update to the /executions route router, so that it can accept a URL parameter.
  • The URL parameter allows specifying the nodeId to be filtered for in the backend/database.

Feedback and suggestions are highly appreciated!

Showcasevideo

bildschirmaufzeichnung-vom-2025-06-05-02-47-12_wKow5MCV.mp4

Review / Merge checklist

  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with release/backport (if the PR is an urgent fix that needs to be backported)

Alex O added 2 commits June 5, 2025 02:24
Introduced the ability to filter executions by specific nodes in both backend and frontend components.
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Alex O seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic found 10 issues across 12 files. Review them in cubic.dev

React with 👍 or 👎 to teach cubic. Tag @cubic-dev-ai to give specific feedback.

@@ -1545,6 +1545,7 @@
"contextMenu.addSticky": "Add sticky note",
"contextMenu.editSticky": "Edit sticky note",
"contextMenu.changeColor": "Change color",
"contextMenu.FilterExecutionsBy": "Filter Executions by",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translation key naming inconsistency. The key uses camelCase 'FilterExecutionsBy' but is referenced in code as 'filter_executions_by'.

Suggested change
"contextMenu.FilterExecutionsBy": "Filter Executions by",
"contextMenu.filter_executions_by": "Filter Executions by",

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change this and some other variables to be consistent with the rest of the naming

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

@@ -51,6 +51,13 @@ const executions = computed(() =>
: [],
);

const FilterExecutionsBy = computed(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule violated: Ensure every PR has unit tests for Vue files

  Missing unit tests for WorkflowExecutionsView.vue component

const idConditions: string[] = [];
query.nodesExecuted.forEach((node, idx) => {
idConditions.push(
`json_type(json_extract(execution_data.data, '$[4].' || :nodeName${idx})) IS NOT NULL`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQL function json_extract may not be compatible with all database types

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this query executed in the sqlite and the postgres setup aswell?
Or only the sqlite?

Cause:
"json_extract is natively supported in modern SQLite versions (3.9.0 and above, released since 2015) if it is compiled with the JSON1 extension—most pre-built binaries include this by default."

const idConditions: string[] = [];
query.nodesExecuted.forEach((node, idx) => {
idConditions.push(
`json_type(json_extract(execution_data.data, '$[4].' || :nodeName${idx})) IS NOT NULL`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded array index '$[4]' in JSON path is brittle and lacks documentation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I analyzed the json in the database and it seems the 4th element is a list where all executed nodes of an execution are listed. so we should always find the node we are searching for in the 4th element.

@@ -1371,6 +1372,7 @@ export type ExecutionsQueryFilter = {
startedBefore?: string;
annotationTags?: string[];
vote?: ExecutionFilterVote;
nodesExecuted: string[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type inconsistency between ExecutionFilterType and ExecutionsQueryFilter interfaces. In ExecutionFilterType, nodesExecuted is optional, but in ExecutionsQueryFilter, it's required. This could cause runtime errors when transforming between these types in executionFilterToQueryFilter function.

Suggested change
nodesExecuted: string[];
+ nodesExecuted?: string[];

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -54,7 +54,11 @@ import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
import Edge from './elements/edges/CanvasEdge.vue';
import Node from './elements/nodes/CanvasNode.vue';
import { useViewportAutoAdjust } from '@/components/canvas/composables/useViewportAutoAdjust';
import { useRouter, useRoute } from 'vue-router';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule violated: Ensure every PR has unit tests for Vue files

  Missing unit tests for the new filter executions functionality

async function onFilterExecutionBy(input: { ids: string[] }) {
const workflowId = route.params.name as string;
if (!workflowId || !input || !input.ids || input.ids.length === 0) return;
const customFilter = nodeDataById.value[input.ids[0]]?.name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing validation for nodeDataById.value[input.ids[0]] existence before accessing name property

Suggested change
const customFilter = nodeDataById.value[input.ids[0]]?.name;
+ const customFilter = nodeDataById.value[input.ids[0]]?.name || undefined;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -961,6 +961,9 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
const qb = this.createQueryBuilder('execution')
.select(fields)
.innerJoin('execution.workflow', 'workflow')
// Add join to execution_data in the query builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment indicates this join might not be needed for all queries, but it's added unconditionally

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have to think about how to solve this better. not every execution needs this join.
feedback is very welcomed here

Copy link
Author

@Alexandero89 Alexandero89 Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implemented a better solution in the new commit. have a look

@@ -182,6 +182,7 @@ export type CanvasEventBusEvents = {
payload?: CanvasNodeEventBusEvents[keyof CanvasNodeEventBusEvents];
};
tidyUp: { source: CanvasLayoutSource };
filter_executions_by: { ids: string[] };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event only uses the first node ID from the array in the implementation, but the type suggests multiple IDs are supported.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this proof of concept i implemented the filtering for only one node.
The idea is later to be able to filter by multiple nodes that are marked.

@@ -699,6 +714,9 @@ async function onContextMenuAction(action: ContextMenuAction, nodeIds: string[])
return await onTidyUp({ source: 'context-menu' });
case 'extract_sub_workflow':
return emit('extract-workflow', nodeIds);
case 'filter_executions_by':
onFilterExecutionBy({ ids: nodeIds });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant function call before emitting the same event

@n8n-assistant n8n-assistant bot added community Authored by a community member core Enhancement outside /nodes-base and /editor-ui in linear Issue or PR has been created in Linear for internal review labels Jun 5, 2025
@Joffcom
Copy link
Member

Joffcom commented Jun 5, 2025

Hey @Alexandero89,

Thanks for the PR, We have created "GHC-2353" as the internal reference to get this reviewed.

One of us will be in touch if there are any changes needed, in most cases this is normally within a couple of weeks but it depends on the current workload of the team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community Authored by a community member core Enhancement outside /nodes-base and /editor-ui in linear Issue or PR has been created in Linear for internal review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants