2022-01-18 18:25:18 +01:00
|
|
|
import {
|
|
|
|
LogicStep,
|
|
|
|
LogicStepType,
|
|
|
|
LogicalOperator,
|
|
|
|
ConditionStep,
|
|
|
|
Variable,
|
|
|
|
ComparisonOperators,
|
2022-01-20 07:21:08 +01:00
|
|
|
SetVariableStep,
|
|
|
|
RedirectStep,
|
2022-02-04 19:00:08 +01:00
|
|
|
Comparison,
|
2022-01-18 18:25:18 +01:00
|
|
|
} from 'models'
|
2022-02-02 08:05:02 +01:00
|
|
|
import { isDefined, isNotDefined } from 'utils'
|
2022-01-20 07:21:08 +01:00
|
|
|
import { sanitizeUrl } from './utils'
|
2022-01-18 18:25:18 +01:00
|
|
|
import { isMathFormula, evaluateExpression, parseVariables } from './variable'
|
|
|
|
|
2022-01-20 07:21:08 +01:00
|
|
|
type EdgeId = string
|
2022-02-04 19:00:08 +01:00
|
|
|
|
2022-01-18 18:25:18 +01:00
|
|
|
export const executeLogic = (
|
|
|
|
step: LogicStep,
|
2022-02-04 19:00:08 +01:00
|
|
|
variables: Variable[],
|
2022-01-18 18:25:18 +01:00
|
|
|
updateVariableValue: (variableId: string, expression: string) => void
|
2022-01-20 07:21:08 +01:00
|
|
|
): EdgeId | undefined => {
|
2022-01-18 18:25:18 +01:00
|
|
|
switch (step.type) {
|
2022-01-20 07:21:08 +01:00
|
|
|
case LogicStepType.SET_VARIABLE:
|
|
|
|
return executeSetVariable(step, variables, updateVariableValue)
|
|
|
|
case LogicStepType.CONDITION:
|
|
|
|
return executeCondition(step, variables)
|
|
|
|
case LogicStepType.REDIRECT:
|
|
|
|
return executeRedirect(step, variables)
|
2022-01-18 18:25:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-20 07:21:08 +01:00
|
|
|
const executeSetVariable = (
|
|
|
|
step: SetVariableStep,
|
2022-02-04 19:00:08 +01:00
|
|
|
variables: Variable[],
|
2022-01-20 07:21:08 +01:00
|
|
|
updateVariableValue: (variableId: string, expression: string) => void
|
|
|
|
): EdgeId | undefined => {
|
|
|
|
if (!step.options?.variableId || !step.options.expressionToEvaluate)
|
2022-02-04 19:00:08 +01:00
|
|
|
return step.outgoingEdgeId
|
2022-01-20 07:21:08 +01:00
|
|
|
const expression = step.options.expressionToEvaluate
|
|
|
|
const evaluatedExpression = isMathFormula(expression)
|
2022-02-07 18:06:37 +01:00
|
|
|
? evaluateExpression(parseVariables(variables)(expression))
|
2022-01-20 07:21:08 +01:00
|
|
|
: expression
|
|
|
|
updateVariableValue(step.options.variableId, evaluatedExpression)
|
2022-02-04 19:00:08 +01:00
|
|
|
return step.outgoingEdgeId
|
2022-01-20 07:21:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const executeCondition = (
|
|
|
|
step: ConditionStep,
|
2022-02-04 19:00:08 +01:00
|
|
|
variables: Variable[]
|
2022-01-20 07:21:08 +01:00
|
|
|
): EdgeId | undefined => {
|
2022-02-04 19:00:08 +01:00
|
|
|
const { content } = step.items[0]
|
2022-01-20 07:21:08 +01:00
|
|
|
const isConditionPassed =
|
2022-02-04 19:00:08 +01:00
|
|
|
content.logicalOperator === LogicalOperator.AND
|
|
|
|
? content.comparisons.every(executeComparison(variables))
|
|
|
|
: content.comparisons.some(executeComparison(variables))
|
|
|
|
return isConditionPassed ? step.items[0].outgoingEdgeId : step.outgoingEdgeId
|
2022-01-20 07:21:08 +01:00
|
|
|
}
|
|
|
|
|
2022-01-18 18:25:18 +01:00
|
|
|
const executeComparison =
|
2022-02-04 19:00:08 +01:00
|
|
|
(variables: Variable[]) => (comparison: Comparison) => {
|
2022-01-18 18:25:18 +01:00
|
|
|
if (!comparison?.variableId) return false
|
2022-02-04 19:00:08 +01:00
|
|
|
const inputValue =
|
|
|
|
variables.find((v) => v.id === comparison.variableId)?.value ?? ''
|
2022-01-18 18:25:18 +01:00
|
|
|
const { value } = comparison
|
2022-02-02 08:05:02 +01:00
|
|
|
if (isNotDefined(value)) return false
|
2022-01-18 18:25:18 +01:00
|
|
|
switch (comparison.comparisonOperator) {
|
|
|
|
case ComparisonOperators.CONTAINS: {
|
|
|
|
return inputValue.includes(value)
|
|
|
|
}
|
|
|
|
case ComparisonOperators.EQUAL: {
|
|
|
|
return inputValue === value
|
|
|
|
}
|
|
|
|
case ComparisonOperators.NOT_EQUAL: {
|
|
|
|
return inputValue !== value
|
|
|
|
}
|
|
|
|
case ComparisonOperators.GREATER: {
|
|
|
|
return parseFloat(inputValue) >= parseFloat(value)
|
|
|
|
}
|
|
|
|
case ComparisonOperators.LESS: {
|
|
|
|
return parseFloat(inputValue) <= parseFloat(value)
|
|
|
|
}
|
|
|
|
case ComparisonOperators.IS_SET: {
|
|
|
|
return isDefined(inputValue) && inputValue.length > 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-20 07:21:08 +01:00
|
|
|
|
|
|
|
const executeRedirect = (
|
|
|
|
step: RedirectStep,
|
2022-02-04 19:00:08 +01:00
|
|
|
variables: Variable[]
|
2022-01-20 07:21:08 +01:00
|
|
|
): EdgeId | undefined => {
|
2022-02-04 19:00:08 +01:00
|
|
|
if (!step.options?.url) return step.outgoingEdgeId
|
2022-01-20 07:21:08 +01:00
|
|
|
window.open(
|
2022-02-07 18:06:37 +01:00
|
|
|
sanitizeUrl(parseVariables(variables)(step.options?.url)),
|
2022-01-20 07:21:08 +01:00
|
|
|
step.options.isNewTab ? '_blank' : '_self'
|
|
|
|
)
|
2022-02-04 19:00:08 +01:00
|
|
|
return step.outgoingEdgeId
|
2022-01-20 07:21:08 +01:00
|
|
|
}
|