feat(core): Add support for partial-match execution filters (#15797)

This commit is contained in:
Daria
2025-06-04 09:37:35 +03:00
committed by GitHub
parent 7639cfbaa7
commit 1335af05d5
8 changed files with 99 additions and 21 deletions

View File

@@ -877,9 +877,10 @@
"executionsFilter.startDate": "Earliest",
"executionsFilter.endDate": "Latest",
"executionsFilter.savedData": "Highlighted data",
"executionsFilter.savedDataExactMatch": "Exact match",
"executionsFilter.savedDataKey": "Key",
"executionsFilter.savedDataKeyPlaceholder": "ID",
"executionsFilter.savedDataValue": "Value (exact match)",
"executionsFilter.savedDataValue": "Value",
"executionsFilter.savedDataValuePlaceholder": "123",
"executionsFilter.reset": "Reset all",
"executionsFilter.customData.inputTooltip": "Upgrade plan to filter executions by custom data set at runtime. {link}",

View File

@@ -1344,6 +1344,7 @@ export interface EnvironmentVariable {
export type ExecutionFilterMetadata = {
key: string;
value: string;
exactMatch?: boolean;
};
export type ExecutionFilterVote = AnnotationVote | 'all';

View File

@@ -17,7 +17,7 @@ const defaultFilterState: ExecutionFilterType = {
annotationTags: [],
startDate: '',
endDate: '',
metadata: [{ key: '', value: '' }],
metadata: [{ key: '', value: '', exactMatch: false }],
vote: 'all',
};

View File

@@ -56,7 +56,7 @@ const getDefaultFilter = (): ExecutionFilterType => ({
annotationTags: [],
startDate: '',
endDate: '',
metadata: [{ key: '', value: '' }],
metadata: [{ key: '', value: '', exactMatch: false }],
vote: 'all',
});
const filter = reactive(getDefaultFilter());
@@ -116,11 +116,16 @@ const countSelectedFilterProps = computed(() => {
// vModel.metadata is a text input and needs a debounced emit to avoid too many requests
// We use the :value and @input combo instead of v-model with this event listener
const onFilterMetaChange = (index: number, prop: keyof ExecutionFilterMetadata, value: string) => {
const onFilterMetaChange = <K extends keyof ExecutionFilterMetadata>(
index: number,
prop: K,
value: ExecutionFilterMetadata[K],
) => {
if (!filter.metadata[index]) {
filter.metadata[index] = {
key: '',
value: '',
exactMatch: false,
};
}
filter.metadata[index][prop] = value;
@@ -327,6 +332,26 @@ onBeforeMount(() => {
@update:model-value="onFilterMetaChange(0, 'key', $event)"
/>
</n8n-tooltip>
<div :class="$style.checkboxWrapper">
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
<template #content>
<i18n-t tag="span" keypath="executionsFilter.customData.inputTooltip">
<template #link>
<a href="#" @click.prevent="goToUpgrade">{{
locale.baseText('executionsFilter.customData.inputTooltip.link')
}}</a>
</template>
</i18n-t>
</template>
<n8n-checkbox
:label="locale.baseText('executionsFilter.savedDataExactMatch')"
:model-value="filter.metadata[0]?.exactMatch"
:disabled="!isAdvancedExecutionFilterEnabled"
data-test-id="execution-filter-saved-data-exact-match-checkbox"
@update:model-value="onFilterMetaChange(0, 'exactMatch', $event)"
/>
</n8n-tooltip>
</div>
<label for="execution-filter-saved-data-value">{{
locale.baseText('executionsFilter.savedDataValue')
}}</label>
@@ -373,6 +398,7 @@ onBeforeMount(() => {
display: inline-block;
font-size: var(--font-size-2xs);
margin: var(--spacing-s) 0 var(--spacing-3xs);
color: var(--color-text-dark);
}
}
@@ -384,6 +410,15 @@ onBeforeMount(() => {
font-size: var(--font-size-3xs);
margin: var(--spacing-4xs) 0 var(--spacing-4xs);
}
.checkboxWrapper {
margin-top: var(--spacing-s);
margin-bottom: var(--spacing-2xs);
label {
margin: 0;
}
}
}
.dates {