2
0

feat(logic): Add Redirect step

This commit is contained in:
Baptiste Arnaud
2022-01-20 07:21:08 +01:00
parent 8bbd8977b2
commit c43fd1d386
14 changed files with 311 additions and 46 deletions

View File

@@ -1,46 +1,64 @@
import {
LogicStep,
Target,
LogicStepType,
LogicalOperator,
ConditionStep,
Table,
Variable,
ComparisonOperators,
SetVariableStep,
RedirectStep,
} from 'models'
import { isDefined } from 'utils'
import { sanitizeUrl } from './utils'
import { isMathFormula, evaluateExpression, parseVariables } from './variable'
type EdgeId = string
export const executeLogic = (
step: LogicStep,
variables: Table<Variable>,
updateVariableValue: (variableId: string, expression: string) => void
): string | undefined => {
): EdgeId | undefined => {
switch (step.type) {
case LogicStepType.SET_VARIABLE: {
if (!step.options?.variableId || !step.options.expressionToEvaluate)
return
const expression = step.options.expressionToEvaluate
const evaluatedExpression = isMathFormula(expression)
? evaluateExpression(parseVariables({ text: expression, variables }))
: expression
updateVariableValue(step.options.variableId, evaluatedExpression)
return
}
case LogicStepType.CONDITION: {
const isConditionPassed =
step.options?.logicalOperator === LogicalOperator.AND
? step.options?.comparisons.allIds.every(
executeComparison(step, variables)
)
: step.options?.comparisons.allIds.some(
executeComparison(step, variables)
)
return isConditionPassed ? step.trueEdgeId : step.falseEdgeId
}
case LogicStepType.SET_VARIABLE:
return executeSetVariable(step, variables, updateVariableValue)
case LogicStepType.CONDITION:
return executeCondition(step, variables)
case LogicStepType.REDIRECT:
return executeRedirect(step, variables)
}
}
const executeSetVariable = (
step: SetVariableStep,
variables: Table<Variable>,
updateVariableValue: (variableId: string, expression: string) => void
): EdgeId | undefined => {
if (!step.options?.variableId || !step.options.expressionToEvaluate)
return step.edgeId
const expression = step.options.expressionToEvaluate
const evaluatedExpression = isMathFormula(expression)
? evaluateExpression(parseVariables({ text: expression, variables }))
: expression
updateVariableValue(step.options.variableId, evaluatedExpression)
return step.edgeId
}
const executeCondition = (
step: ConditionStep,
variables: Table<Variable>
): EdgeId | undefined => {
const isConditionPassed =
step.options?.logicalOperator === LogicalOperator.AND
? step.options?.comparisons.allIds.every(
executeComparison(step, variables)
)
: step.options?.comparisons.allIds.some(
executeComparison(step, variables)
)
return isConditionPassed ? step.trueEdgeId : step.falseEdgeId
}
const executeComparison =
(step: ConditionStep, variables: Table<Variable>) =>
(comparisonId: string) => {
@@ -70,3 +88,15 @@ const executeComparison =
}
}
}
const executeRedirect = (
step: RedirectStep,
variables: Table<Variable>
): EdgeId | undefined => {
if (!step.options?.url) return step.edgeId
window.open(
sanitizeUrl(parseVariables({ text: step.options?.url, variables })),
step.options.isNewTab ? '_blank' : '_self'
)
return step.edgeId
}

View File

@@ -0,0 +1,7 @@
export const sanitizeUrl = (url: string): string =>
url.startsWith('http') ||
url.startsWith('mailto:') ||
url.startsWith('tel:') ||
url.startsWith('sms:')
? url
: `https://${url}`

View File

@@ -1,20 +1,36 @@
import { StepBase } from '.'
import { Table } from '../..'
export type LogicStep = SetVariableStep | ConditionStep
export type LogicStep = SetVariableStep | ConditionStep | RedirectStep
export enum LogicStepType {
SET_VARIABLE = 'Set variable',
CONDITION = 'Condition',
REDIRECT = 'Redirect',
}
export type LogicStepOptions = SetVariableOptions | ConditionOptions
export type LogicStepOptions =
| SetVariableOptions
| ConditionOptions
| RedirectOptions
export type SetVariableStep = StepBase & {
type: LogicStepType.SET_VARIABLE
options?: SetVariableOptions
}
export type ConditionStep = StepBase & {
type: LogicStepType.CONDITION
options: ConditionOptions
trueEdgeId?: string
falseEdgeId?: string
}
export type RedirectStep = StepBase & {
type: LogicStepType.REDIRECT
options?: RedirectOptions
}
export enum LogicalOperator {
OR = 'OR',
AND = 'AND',
@@ -29,13 +45,6 @@ export enum ComparisonOperators {
IS_SET = 'Is set',
}
export type ConditionStep = StepBase & {
type: LogicStepType.CONDITION
options: ConditionOptions
trueEdgeId?: string
falseEdgeId?: string
}
export type ConditionOptions = {
comparisons: Table<Comparison>
logicalOperator?: LogicalOperator
@@ -52,3 +61,8 @@ export type SetVariableOptions = {
variableId?: string
expressionToEvaluate?: string
}
export type RedirectOptions = {
url?: string
isNewTab?: boolean
}