diff --git a/webapp/components/expression/nodes/binaryOperand.js b/webapp/components/expression/nodes/binaryOperand.js index accc398986..a2bdf53e0c 100644 --- a/webapp/components/expression/nodes/binaryOperand.js +++ b/webapp/components/expression/nodes/binaryOperand.js @@ -8,22 +8,24 @@ import * as ProcessUtils from '@core/processUtils' import { Button } from '@webapp/components/buttons' +const { types } = Expression + const availableOperandExpressionTypes = [ - Expression.types.Identifier, - Expression.types.Literal, - ...(ProcessUtils.ENV.experimentalFeatures ? [Expression.types.CallExpression] : []), + types.Identifier, + types.Literal, + ...(ProcessUtils.ENV.experimentalFeatures ? [types.CallExpression] : []), ] const expressionTypeAcronymByType = { - [Expression.types.CallExpression]: 'call', - [Expression.types.Identifier]: 'var', - [Expression.types.Literal]: 'const', + [types.CallExpression]: 'call', + [types.Identifier]: 'var', + [types.Literal]: 'const', } const expressionGeneratorByType = { - [Expression.types.CallExpression]: () => Expression.newCall(), - [Expression.types.Identifier]: () => Expression.newIdentifier(), - [Expression.types.Literal]: () => Expression.newLiteral(), + [types.CallExpression]: () => Expression.newCall(), + [types.Identifier]: () => Expression.newIdentifier(), + [types.Literal]: () => Expression.newLiteral(), } const BinaryOperandExpressionTypeButton = (props) => { @@ -54,6 +56,14 @@ export const BinaryOperandType = { BinaryOperandType.isLeft = (type) => type === BinaryOperandType.left BinaryOperandType.isRight = (type) => type === BinaryOperandType.right +const toUiOperandExpressionType = (type) => { + if (type === types.UnaryExpression) { + // unary expressions managed as literal expressions in UI + return types.Literal + } + return type +} + const BinaryOperand = (props) => { const { canDelete = false, @@ -69,17 +79,17 @@ const BinaryOperand = (props) => { } = props const nodeOperand = node[type] - const operandExpressionType = Expression.getType(nodeOperand) + const operandExpressionType = toUiOperandExpressionType(Expression.getType(nodeOperand)) const isLeft = BinaryOperandType.isLeft(type) const currentNodeDefIsBoolean = NodeDef.isBoolean(nodeDefCurrent) const canOperandExpressionBeOfType = useCallback( (expressionType) => { switch (expressionType) { - case Expression.types.Identifier: - case Expression.types.CallExpression: + case types.Identifier: + case types.CallExpression: return true - case Expression.types.Literal: + case types.Literal: return !isLeft || !isBoolean || currentNodeDefIsBoolean default: return false diff --git a/webapp/components/expression/nodes/expressionNode.js b/webapp/components/expression/nodes/expressionNode.js index 807835597b..b2579a9f52 100644 --- a/webapp/components/expression/nodes/expressionNode.js +++ b/webapp/components/expression/nodes/expressionNode.js @@ -10,16 +10,38 @@ import Literal from './literal' import Logical from './logical' import Member from './member' +const { types } = Expression + const componentFns = { - [Expression.types.Identifier]: () => Identifier, - [Expression.types.MemberExpression]: () => Member, - [Expression.types.Literal]: () => Literal, - [Expression.types.CallExpression]: () => Call, - [Expression.types.BinaryExpression]: (expressionNode) => { + [types.Identifier]: () => Identifier, + [types.MemberExpression]: () => Member, + [types.Literal]: () => Literal, + [types.CallExpression]: () => Call, + [types.BinaryExpression]: (expressionNode) => { const { logical: logicalOperators } = Expression.operators return [logicalOperators.or.value, logicalOperators.and.value].includes(expressionNode.operator) ? Logical : Binary }, - [Expression.types.SequenceExpression]: () => Sequence, + [types.SequenceExpression]: () => Sequence, +} + +const thisExpressionNode = { type: types.Identifier, name: Expression.thisVariable } + +const toUiComponentNode = (node) => { + const { type } = node + if (type === types.ThisExpression) { + return thisExpressionNode + } + if (type === types.UnaryExpression) { + // e.g. this > -1 ; -1 is a unary expression (value 1, operator -) + // in the expression editor it will be managed as a literal expression, with a value of "-1" + const { argument } = node + const { type: argumentType, value: argumentValue } = argument ?? {} + if (argumentType === types.Literal) { + const newValue = `${node.operator} ${argumentValue}` + return Expression.newLiteral(newValue) + } + } + return node } const ExpressionNode = (props) => { @@ -36,11 +58,8 @@ const ExpressionNode = (props) => { variables = null, } = props - // transform a "this" expression into an Identifier expression - const componentNode = - node.type === Expression.types.ThisExpression - ? { type: Expression.types.Identifier, name: Expression.thisVariable } - : node + const componentNode = toUiComponentNode(node) + if (!componentNode) return null const componentFn = componentFns[componentNode.type] const component = componentFn(componentNode)