mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(Data Table Node): Update ResourceMapper Copy (no-changelog) (#19048)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import type { DataStoreColumnJsType } from 'n8n-workflow';
|
||||
|
||||
export const ANY_FILTER = 'anyFilter';
|
||||
export const ALL_FILTERS = 'allFilters';
|
||||
export const ANY_CONDITION = 'anyCondition';
|
||||
export const ALL_CONDITIONS = 'allConditions';
|
||||
|
||||
export type FilterType = typeof ANY_FILTER | typeof ALL_FILTERS;
|
||||
export type FilterType = typeof ANY_CONDITION | typeof ALL_CONDITIONS;
|
||||
|
||||
export type FieldEntry =
|
||||
| {
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { FilterType } from './constants';
|
||||
import { ALL_CONDITIONS, ANY_CONDITION, type FilterType } from './constants';
|
||||
import { DATA_TABLE_ID_FIELD } from './fields';
|
||||
import { buildGetManyFilter, isFieldArray, isMatchType } from './utils';
|
||||
|
||||
@@ -22,16 +22,16 @@ export function getSelectFields(
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Any Filter',
|
||||
value: 'anyFilter',
|
||||
name: 'Any Condition',
|
||||
value: ANY_CONDITION,
|
||||
},
|
||||
{
|
||||
name: 'All Filters',
|
||||
value: 'allFilters',
|
||||
name: 'All Conditions',
|
||||
value: ALL_CONDITIONS,
|
||||
},
|
||||
] satisfies Array<{ value: FilterType; name: string }>,
|
||||
displayOptions,
|
||||
default: 'anyFilter',
|
||||
default: ANY_CONDITION,
|
||||
},
|
||||
{
|
||||
displayName: 'Conditions',
|
||||
@@ -50,11 +50,13 @@ export function getSelectFields(
|
||||
name: 'conditions',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field Name or ID',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column',
|
||||
name: 'keyName',
|
||||
type: 'options',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
||||
'Choose from the list, or specify using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: [DATA_TABLE_ID_FIELD],
|
||||
loadOptionsMethod: 'getDataTableColumns',
|
||||
@@ -74,7 +76,7 @@ export function getSelectFields(
|
||||
default: 'eq',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
displayName: 'Value',
|
||||
name: 'keyValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
@@ -94,7 +96,7 @@ export function getSelectFields(
|
||||
|
||||
export function getSelectFilter(ctx: IExecuteFunctions, index: number) {
|
||||
const fields = ctx.getNodeParameter('filters.conditions', index, []);
|
||||
const matchType = ctx.getNodeParameter('matchType', index, 'anyFilter');
|
||||
const matchType = ctx.getNodeParameter('matchType', index, ANY_CONDITION);
|
||||
const node = ctx.getNode();
|
||||
|
||||
if (!isMatchType(matchType)) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import type {
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import type { FieldEntry, FilterType } from './constants';
|
||||
import { ALL_FILTERS, ANY_FILTER } from './constants';
|
||||
import { ALL_CONDITIONS, ANY_CONDITION } from './constants';
|
||||
import { DATA_TABLE_ID_FIELD } from './fields';
|
||||
|
||||
type DateLike = { toISOString: () => string };
|
||||
@@ -76,7 +76,7 @@ export function isFieldEntry(obj: unknown): obj is FieldEntry {
|
||||
}
|
||||
|
||||
export function isMatchType(obj: unknown): obj is FilterType {
|
||||
return typeof obj === 'string' && (obj === ANY_FILTER || obj === ALL_FILTERS);
|
||||
return typeof obj === 'string' && (obj === ANY_CONDITION || obj === ALL_CONDITIONS);
|
||||
}
|
||||
|
||||
export function buildGetManyFilter(
|
||||
@@ -105,7 +105,7 @@ export function buildGetManyFilter(
|
||||
};
|
||||
}
|
||||
});
|
||||
return { type: matchType === 'allFilters' ? 'and' : 'or', filters };
|
||||
return { type: matchType === ALL_CONDITIONS ? 'and' : 'or', filters };
|
||||
}
|
||||
|
||||
export function isFieldArray(value: unknown): value is FieldEntry[] {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { FieldEntry } from '../../common/constants';
|
||||
import { ANY_FILTER, ALL_FILTERS } from '../../common/constants';
|
||||
import { ANY_CONDITION, ALL_CONDITIONS } from '../../common/constants';
|
||||
import { DATA_TABLE_ID_FIELD } from '../../common/fields';
|
||||
import { executeSelectMany } from '../../common/selectMany';
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('selectMany utils', () => {
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ANY_FILTER;
|
||||
return ANY_CONDITION;
|
||||
}
|
||||
}),
|
||||
} as unknown as IExecuteFunctions;
|
||||
@@ -226,7 +226,7 @@ describe('selectMany utils', () => {
|
||||
expect(result).toEqual([{ json: { id: 1, name: 'Anne-Marie' } }]);
|
||||
});
|
||||
|
||||
it('should handle multiple conditions with ANY_FILTER (OR logic - matches records satisfying either condition)', async () => {
|
||||
it('should handle multiple conditions with ANY_CONDITION (OR logic - matches records satisfying either condition)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'active' },
|
||||
@@ -244,7 +244,7 @@ describe('selectMany utils', () => {
|
||||
expect(result).toEqual([{ json: { id: 1, status: 'active', age: 25 } }]);
|
||||
});
|
||||
|
||||
it('should handle multiple conditions with ALL_FILTERS (AND logic - matches records satisfying all conditions)', async () => {
|
||||
it('should handle multiple conditions with ALL_CONDITIONS (AND logic - matches records satisfying all conditions)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'active' },
|
||||
@@ -257,7 +257,7 @@ describe('selectMany utils', () => {
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ALL_FILTERS;
|
||||
return ALL_CONDITIONS;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
@@ -272,7 +272,7 @@ describe('selectMany utils', () => {
|
||||
expect(result).toEqual([{ json: { id: 1, status: 'active', age: 25 } }]);
|
||||
});
|
||||
|
||||
it('should handle ALL_FILTERS excluding records that match only one condition (proves AND logic)', async () => {
|
||||
it('should handle ALL_CONDITIONS excluding records that match only one condition (proves AND logic)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'inactive' },
|
||||
@@ -285,7 +285,7 @@ describe('selectMany utils', () => {
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ALL_FILTERS;
|
||||
return ALL_CONDITIONS;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
@@ -300,7 +300,7 @@ describe('selectMany utils', () => {
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle ANY_FILTER including records that match only one condition (proves OR logic)', async () => {
|
||||
it('should handle ANY_CONDITION including records that match only one condition (proves OR logic)', async () => {
|
||||
// ARRANGE
|
||||
filters = [
|
||||
{ condition: 'eq', keyName: 'status', keyValue: 'inactive' },
|
||||
@@ -313,7 +313,7 @@ describe('selectMany utils', () => {
|
||||
case 'filters.conditions':
|
||||
return filters;
|
||||
case 'matchType':
|
||||
return ANY_FILTER;
|
||||
return ANY_CONDITION;
|
||||
}
|
||||
});
|
||||
getManyRowsAndCount.mockReturnValue({
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DateTime } from 'luxon';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import { ANY_CONDITION, ALL_CONDITIONS } from '../../common/constants';
|
||||
import { dataObjectToApiInput, buildGetManyFilter } from '../../common/utils';
|
||||
|
||||
const mockNode: INode = {
|
||||
@@ -206,7 +207,7 @@ describe('buildGetManyFilter - isEmpty/isNotEmpty translation', () => {
|
||||
it('should translate isEmpty to eq with null value', () => {
|
||||
const fieldEntries = [{ keyName: 'name', condition: 'isEmpty' as const, keyValue: 'ignored' }];
|
||||
|
||||
const result = buildGetManyFilter(fieldEntries, 'allFilters');
|
||||
const result = buildGetManyFilter(fieldEntries, ALL_CONDITIONS);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'and',
|
||||
@@ -225,7 +226,7 @@ describe('buildGetManyFilter - isEmpty/isNotEmpty translation', () => {
|
||||
{ keyName: 'email', condition: 'isNotEmpty' as const, keyValue: 'ignored' },
|
||||
];
|
||||
|
||||
const result = buildGetManyFilter(fieldEntries, 'anyFilter');
|
||||
const result = buildGetManyFilter(fieldEntries, ANY_CONDITION);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'or',
|
||||
@@ -246,7 +247,7 @@ describe('buildGetManyFilter - isEmpty/isNotEmpty translation', () => {
|
||||
{ keyName: 'phone', condition: 'isNotEmpty' as const, keyValue: 'ignored' },
|
||||
];
|
||||
|
||||
const result = buildGetManyFilter(fieldEntries, 'allFilters');
|
||||
const result = buildGetManyFilter(fieldEntries, ALL_CONDITIONS);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'and',
|
||||
@@ -276,7 +277,7 @@ describe('buildGetManyFilter - isEmpty/isNotEmpty translation', () => {
|
||||
{ keyName: 'name', condition: 'like' as const, keyValue: '%john%' },
|
||||
];
|
||||
|
||||
const result = buildGetManyFilter(fieldEntries, 'anyFilter');
|
||||
const result = buildGetManyFilter(fieldEntries, ANY_CONDITION);
|
||||
|
||||
expect(result).toEqual({
|
||||
type: 'or',
|
||||
|
||||
Reference in New Issue
Block a user