mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(editor): Add isEmpty on DateTime, add is empty to all types in filter component (#9645)
This commit is contained in:
@@ -352,7 +352,7 @@ compact.doc = {
|
||||
|
||||
isEmpty.doc = {
|
||||
name: 'isEmpty',
|
||||
description: 'Returns <code>true</code> if the array has no elements',
|
||||
description: 'Returns <code>true</code> if the array has no elements or is <code>null</code>',
|
||||
examples: [
|
||||
{ example: '[].isEmpty()', evaluated: 'true' },
|
||||
{ example: "['quick', 'brown', 'fox'].isEmpty()", evaluated: 'false' },
|
||||
|
||||
@@ -278,6 +278,15 @@ function toBoolean() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Only null/undefined return true, this is handled in ExpressionExtension.ts
|
||||
function isEmpty(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isNotEmpty(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
endOfMonth.doc = {
|
||||
name: 'endOfMonth',
|
||||
returnType: 'DateTime',
|
||||
@@ -547,7 +556,7 @@ diffToNow.doc = {
|
||||
evaluated: '371.9',
|
||||
},
|
||||
{
|
||||
example: "dt = '2023-03-30T18:49:07.234.toDateTime()\ndt.diffToNow(['months', 'days'])",
|
||||
example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.diffToNow(['months', 'days'])",
|
||||
evaluated: '{ months: 12, days: 5.9 }',
|
||||
},
|
||||
],
|
||||
@@ -565,6 +574,30 @@ diffToNow.doc = {
|
||||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/dates/#date-diffToNow',
|
||||
};
|
||||
|
||||
isEmpty.doc = {
|
||||
name: 'isEmpty',
|
||||
description:
|
||||
'Returns <code>false</code> for all DateTimes. Returns <code>true</code> for <code>null</code>.',
|
||||
examples: [
|
||||
{ example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.isEmpty()", evaluated: 'false' },
|
||||
{ example: 'dt = null\ndt.isEmpty()', evaluated: 'true' },
|
||||
],
|
||||
returnType: 'boolean',
|
||||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/arrays/#array-isEmpty',
|
||||
};
|
||||
|
||||
isNotEmpty.doc = {
|
||||
name: 'isNotEmpty',
|
||||
description:
|
||||
'Returns <code>true</code> for all DateTimes. Returns <code>false</code> for <code>null</code>.',
|
||||
examples: [
|
||||
{ example: "dt = '2023-03-30T18:49:07.234'.toDateTime()\ndt.isNotEmpty()", evaluated: 'true' },
|
||||
{ example: 'dt = null\ndt.isNotEmpty()', evaluated: 'false' },
|
||||
],
|
||||
returnType: 'boolean',
|
||||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/arrays/#array-isNotEmpty',
|
||||
};
|
||||
|
||||
export const dateExtensions: ExtensionMap = {
|
||||
typeName: 'Date',
|
||||
functions: {
|
||||
@@ -584,5 +617,7 @@ export const dateExtensions: ExtensionMap = {
|
||||
toInt,
|
||||
toFloat,
|
||||
toBoolean,
|
||||
isEmpty,
|
||||
isNotEmpty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -110,7 +110,8 @@ export function toDateTime() {
|
||||
|
||||
isEmpty.doc = {
|
||||
name: 'isEmpty',
|
||||
description: 'Returns <code>true</code> if the Object has no keys (fields) set',
|
||||
description:
|
||||
'Returns <code>true</code> if the Object has no keys (fields) set or is <code>null</code>',
|
||||
examples: [
|
||||
{ example: "({'name': 'Nathan'}).isEmpty()", evaluated: 'false' },
|
||||
{ example: '({}).isEmpty()', evaluated: 'true' },
|
||||
|
||||
@@ -676,7 +676,7 @@ isUrl.doc = {
|
||||
|
||||
isEmpty.doc = {
|
||||
name: 'isEmpty',
|
||||
description: 'Returns <code>true</code> if the string has no characters.',
|
||||
description: 'Returns <code>true</code> if the string has no characters or is <code>null</code>',
|
||||
section: 'validation',
|
||||
returnType: 'boolean',
|
||||
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isEmpty',
|
||||
|
||||
@@ -212,6 +212,10 @@ export function executeFilterCondition(
|
||||
const right = rightValue as number;
|
||||
|
||||
switch (condition.operator.operation) {
|
||||
case 'empty':
|
||||
return !exists;
|
||||
case 'notEmpty':
|
||||
return exists;
|
||||
case 'equals':
|
||||
return left === right;
|
||||
case 'notEquals':
|
||||
@@ -230,6 +234,12 @@ export function executeFilterCondition(
|
||||
const left = leftValue as DateTime;
|
||||
const right = rightValue as DateTime;
|
||||
|
||||
if (condition.operator.operation === 'empty') {
|
||||
return !exists;
|
||||
} else if (condition.operator.operation === 'notEmpty') {
|
||||
return exists;
|
||||
}
|
||||
|
||||
if (!left || !right) {
|
||||
return false;
|
||||
}
|
||||
@@ -254,6 +264,10 @@ export function executeFilterCondition(
|
||||
const right = rightValue as boolean;
|
||||
|
||||
switch (condition.operator.operation) {
|
||||
case 'empty':
|
||||
return !exists;
|
||||
case 'notEmpty':
|
||||
return exists;
|
||||
case 'true':
|
||||
return left;
|
||||
case 'false':
|
||||
|
||||
@@ -570,6 +570,48 @@ describe('FilterParameter', () => {
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: 0, expected: false },
|
||||
{ left: 15, expected: false },
|
||||
{ left: -15.4, expected: false },
|
||||
{ left: NaN, expected: true },
|
||||
{ left: null, expected: true },
|
||||
])('number:empty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'empty', type: 'number' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: 0, expected: true },
|
||||
{ left: 15, expected: true },
|
||||
{ left: -15.4, expected: true },
|
||||
{ left: NaN, expected: false },
|
||||
{ left: null, expected: false },
|
||||
])('number:notEmpty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'notEmpty', type: 'number' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: 0, right: 0, expected: true },
|
||||
{ left: 15, right: 15, expected: true },
|
||||
@@ -706,6 +748,42 @@ describe('FilterParameter', () => {
|
||||
});
|
||||
|
||||
describe('dateTime', () => {
|
||||
it.each([
|
||||
{ left: '2023-11-15T17:10:49.113Z', expected: false },
|
||||
{ left: null, expected: true },
|
||||
])('dateTime:empty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'empty', type: 'dateTime' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: '2023-11-15T17:10:49.113Z', expected: true },
|
||||
{ left: null, expected: false },
|
||||
])('dateTime:notEmpty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'notEmpty', type: 'dateTime' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: '2023-11-15T17:10:49.113Z', right: '2023-11-15T17:10:49.113Z', expected: true },
|
||||
{ left: '2023-11-15T17:10:49.113Z', right: '2023-11-15T17:12:49.113Z', expected: false },
|
||||
@@ -838,6 +916,44 @@ describe('FilterParameter', () => {
|
||||
});
|
||||
|
||||
describe('boolean', () => {
|
||||
it.each([
|
||||
{ left: true, expected: false },
|
||||
{ left: false, expected: false },
|
||||
{ left: null, expected: true },
|
||||
])('boolean:empty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'empty', type: 'boolean' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: true, expected: true },
|
||||
{ left: false, expected: true },
|
||||
{ left: null, expected: false },
|
||||
])('boolean:notEmpty($left) === $expected', ({ left, expected }) => {
|
||||
const result = executeFilter(
|
||||
filterFactory({
|
||||
conditions: [
|
||||
{
|
||||
id: '1',
|
||||
leftValue: left,
|
||||
operator: { operation: 'notEmpty', type: 'boolean' },
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ left: true, expected: true },
|
||||
{ left: false, expected: false },
|
||||
|
||||
Reference in New Issue
Block a user