mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
✨ Add DateTime support to IF and Switch-Node
This commit is contained in:
parent
85703a8bf7
commit
17fb31920e
|
@ -73,6 +73,43 @@ export class If implements INodeType {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'dateTime',
|
||||||
|
displayName: 'DateTime',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Value 1',
|
||||||
|
name: 'value1',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'The value to compare with the second one.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'After',
|
||||||
|
value: 'after',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Before',
|
||||||
|
value: 'before',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'after',
|
||||||
|
description: 'Operation to decide where the the data should be mapped to.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value 2',
|
||||||
|
name: 'value2',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'The value to compare with the first one.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'number',
|
name: 'number',
|
||||||
displayName: 'Number',
|
displayName: 'Number',
|
||||||
|
@ -259,6 +296,8 @@ export class If implements INodeType {
|
||||||
const compareOperationFunctions: {
|
const compareOperationFunctions: {
|
||||||
[key: string]: (value1: NodeParameterValue, value2: NodeParameterValue) => boolean;
|
[key: string]: (value1: NodeParameterValue, value2: NodeParameterValue) => boolean;
|
||||||
} = {
|
} = {
|
||||||
|
after: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) > (value2 || 0),
|
||||||
|
before: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) < (value2 || 0),
|
||||||
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
||||||
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
||||||
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
||||||
|
@ -286,9 +325,28 @@ export class If implements INodeType {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Converts the input data of a dateTime into a number for easy compare
|
||||||
|
function convertDateTime(value: NodeParameterValue): number {
|
||||||
|
let returnValue: number | undefined = undefined;
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
returnValue = new Date(value).getTime();
|
||||||
|
} else if (typeof value === 'number') {
|
||||||
|
returnValue = value;
|
||||||
|
} if ((value as any) instanceof Date) {
|
||||||
|
returnValue = (value as unknown as Date).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue === undefined || isNaN(returnValue)) {
|
||||||
|
throw new Error(`The value "${value}" is not a valid DateTime.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
// The different dataTypes to check the values in
|
// The different dataTypes to check the values in
|
||||||
const dataTypes = [
|
const dataTypes = [
|
||||||
'boolean',
|
'boolean',
|
||||||
|
'dateTime',
|
||||||
'number',
|
'number',
|
||||||
'string',
|
'string',
|
||||||
];
|
];
|
||||||
|
@ -297,6 +355,7 @@ export class If implements INodeType {
|
||||||
// which ones via output "false"
|
// which ones via output "false"
|
||||||
let dataType: string;
|
let dataType: string;
|
||||||
let compareOperationResult: boolean;
|
let compareOperationResult: boolean;
|
||||||
|
let value1: NodeParameterValue, value2: NodeParameterValue;
|
||||||
itemLoop:
|
itemLoop:
|
||||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||||
item = items[itemIndex];
|
item = items[itemIndex];
|
||||||
|
@ -310,7 +369,16 @@ export class If implements INodeType {
|
||||||
// Check all the values of the current dataType
|
// Check all the values of the current dataType
|
||||||
for (compareData of this.getNodeParameter(`conditions.${dataType}`, itemIndex, []) as INodeParameters[]) {
|
for (compareData of this.getNodeParameter(`conditions.${dataType}`, itemIndex, []) as INodeParameters[]) {
|
||||||
// Check if the values passes
|
// Check if the values passes
|
||||||
compareOperationResult = compareOperationFunctions[compareData.operation as string](compareData.value1 as NodeParameterValue, compareData.value2 as NodeParameterValue);
|
|
||||||
|
value1 = compareData.value1 as NodeParameterValue;
|
||||||
|
value2 = compareData.value2 as NodeParameterValue;
|
||||||
|
|
||||||
|
if (dataType === 'dateTime') {
|
||||||
|
value1 = convertDateTime(value1);
|
||||||
|
value2 = convertDateTime(value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
compareOperationResult = compareOperationFunctions[compareData.operation as string](value1, value2);
|
||||||
|
|
||||||
if (compareOperationResult === true && combineOperation === 'any') {
|
if (compareOperationResult === true && combineOperation === 'any') {
|
||||||
// If it passes and the operation is "any" we do not have to check any
|
// If it passes and the operation is "any" we do not have to check any
|
||||||
|
|
|
@ -87,6 +87,10 @@ export class Switch implements INodeType {
|
||||||
name: 'Boolean',
|
name: 'Boolean',
|
||||||
value: 'boolean',
|
value: 'boolean',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'DateTime',
|
||||||
|
value: 'dateTime',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Number',
|
name: 'Number',
|
||||||
value: 'number',
|
value: 'number',
|
||||||
|
@ -185,6 +189,91 @@ export class Switch implements INodeType {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// dataType:dateTime
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Value 1',
|
||||||
|
name: 'value1',
|
||||||
|
type: 'dateTime',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType: [
|
||||||
|
'dateTime',
|
||||||
|
],
|
||||||
|
mode: [
|
||||||
|
'rules',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'The value to compare with the second one.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Routing Rules',
|
||||||
|
name: 'rules',
|
||||||
|
placeholder: 'Add Routing Rule',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType: [
|
||||||
|
'dateTime',
|
||||||
|
],
|
||||||
|
mode: [
|
||||||
|
'rules',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The routing rules.',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'rules',
|
||||||
|
displayName: 'Dates',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'After',
|
||||||
|
value: 'after',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Before',
|
||||||
|
value: 'before',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'after',
|
||||||
|
description: 'Operation to decide where the the data should be mapped to.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value 2',
|
||||||
|
name: 'value2',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: 0,
|
||||||
|
description: 'The value to compare with the first one.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Output',
|
||||||
|
name: 'output',
|
||||||
|
type: 'number',
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 0,
|
||||||
|
maxValue: 3,
|
||||||
|
},
|
||||||
|
default: 0,
|
||||||
|
description: 'The index of output to which to send data to if rule matches.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// dataType:number
|
// dataType:number
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
@ -470,12 +559,14 @@ export class Switch implements INodeType {
|
||||||
let mode: string;
|
let mode: string;
|
||||||
let outputIndex: number;
|
let outputIndex: number;
|
||||||
let ruleData: INodeParameters;
|
let ruleData: INodeParameters;
|
||||||
let value1: NodeParameterValue;
|
let value1: NodeParameterValue, value2: NodeParameterValue;
|
||||||
|
|
||||||
// The compare operations
|
// The compare operations
|
||||||
const compareOperationFunctions: {
|
const compareOperationFunctions: {
|
||||||
[key: string]: (value1: NodeParameterValue, value2: NodeParameterValue) => boolean;
|
[key: string]: (value1: NodeParameterValue, value2: NodeParameterValue) => boolean;
|
||||||
} = {
|
} = {
|
||||||
|
after: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) > (value2 || 0),
|
||||||
|
before: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) < (value2 || 0),
|
||||||
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
||||||
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
||||||
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
||||||
|
@ -502,12 +593,32 @@ export class Switch implements INodeType {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Converts the input data of a dateTime into a number for easy compare
|
||||||
|
function convertDateTime(value: NodeParameterValue): number {
|
||||||
|
let returnValue: number | undefined = undefined;
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
returnValue = new Date(value).getTime();
|
||||||
|
} else if (typeof value === 'number') {
|
||||||
|
returnValue = value;
|
||||||
|
} if ((value as any) instanceof Date) {
|
||||||
|
returnValue = (value as unknown as Date).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue === undefined || isNaN(returnValue)) {
|
||||||
|
throw new Error(`The value "${value}" is not a valid DateTime.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
function checkIndexRange(index: number) {
|
function checkIndexRange(index: number) {
|
||||||
if (index < 0 || index >= returnData.length) {
|
if (index < 0 || index >= returnData.length) {
|
||||||
throw new Error(`The ouput ${index} is not allowed. It has to be between 0 and ${returnData.length - 1}!`);
|
throw new Error(`The ouput ${index} is not allowed. It has to be between 0 and ${returnData.length - 1}!`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataType = this.getNodeParameter('dataType', 0) as string;
|
||||||
|
|
||||||
// Itterate over all items to check to which output they should be routed to
|
// Itterate over all items to check to which output they should be routed to
|
||||||
itemLoop:
|
itemLoop:
|
||||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||||
|
@ -525,10 +636,19 @@ export class Switch implements INodeType {
|
||||||
// Rules decide how to route item
|
// Rules decide how to route item
|
||||||
|
|
||||||
value1 = this.getNodeParameter('value1', itemIndex) as NodeParameterValue;
|
value1 = this.getNodeParameter('value1', itemIndex) as NodeParameterValue;
|
||||||
|
if (dataType === 'dateTime') {
|
||||||
|
value1 = convertDateTime(value1);
|
||||||
|
}
|
||||||
|
|
||||||
for (ruleData of this.getNodeParameter('rules.rules', itemIndex, []) as INodeParameters[]) {
|
for (ruleData of this.getNodeParameter('rules.rules', itemIndex, []) as INodeParameters[]) {
|
||||||
// Check if the values passes
|
// Check if the values passes
|
||||||
compareOperationResult = compareOperationFunctions[ruleData.operation as string](value1, ruleData.value2 as NodeParameterValue);
|
|
||||||
|
value2 = ruleData.value2 as NodeParameterValue;
|
||||||
|
if (dataType === 'dateTime') {
|
||||||
|
value2 = convertDateTime(value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
compareOperationResult = compareOperationFunctions[ruleData.operation as string](value1, value2);
|
||||||
|
|
||||||
if (compareOperationResult === true) {
|
if (compareOperationResult === true) {
|
||||||
// If rule matches add it to the correct output and continue with next item
|
// If rule matches add it to the correct output and continue with next item
|
||||||
|
|
Loading…
Reference in a new issue