diff --git a/core/i18n/resources/en/common.js b/core/i18n/resources/en/common.js index 8edb21f6f3..935186b9b6 100644 --- a/core/i18n/resources/en/common.js +++ b/core/i18n/resources/en/common.js @@ -1859,6 +1859,8 @@ Levels will be renamed into level_1, level_2... level_N and an extra 'area' prop call: 'Function', operator: 'Operator', + coordinateAttributeWithPosition: 'Coordinate attribute {{position}}', + error: { selectOneVariable: 'Please select one variable', }, diff --git a/webapp/components/expression/nodes/call/callDistanceEditor.js b/webapp/components/expression/nodes/call/callDistanceEditor.js new file mode 100644 index 0000000000..93f557b5a9 --- /dev/null +++ b/webapp/components/expression/nodes/call/callDistanceEditor.js @@ -0,0 +1,81 @@ +import React, { useCallback, useState } from 'react' + +import { Arrays } from '@openforis/arena-core' + +import * as NodeDef from '@core/survey/nodeDef' +import * as Expression from '@core/expressionParser/expression' + +import { Button } from '@webapp/components/buttons' +import { FormItem } from '@webapp/components/form/Input' + +import Identifier from '../identifier' +import { CallEditorPropTypes } from './callEditorPropTypes' + +const variablesFilterFn = (variable) => variable.root || variable.nodeDefType === NodeDef.nodeDefType.coordinate + +export const CallDistanceEditor = (props) => { + const { expressionNode, onConfirm: onConfirmProp, variables } = props + + const identifierArguments = expressionNode?.arguments ?? [] + + const [state, setState] = useState({ + dirty: !identifierArguments?.[0] || !identifierArguments?.[1], + identifierParams: identifierArguments, + }) + + const { dirty, identifierParams } = state + + const onIdentifierParamChange = useCallback( + (paramIndex) => (identifierUpdated) => + setState((statePrev) => { + const identifierParamsUpdated = [...statePrev.identifierParams] + const identifierParamUpdated = identifierUpdated?.name + ? { type: Expression.types.Identifier, ...identifierUpdated } + : null + identifierParamsUpdated[paramIndex] = identifierParamUpdated + return { + ...statePrev, + dirty: true, + identifierParams: identifierParamsUpdated, + } + }), + [] + ) + + const buildFunctionCall = useCallback(() => { + const params = identifierParams + return Expression.newCall({ callee: Expression.functionNames.distance, params }) + }, [identifierParams]) + + const onConfirm = useCallback(() => { + onConfirmProp(buildFunctionCall()) + setState((statePrev) => ({ ...statePrev, dirty: false })) + }, [buildFunctionCall, onConfirmProp]) + + return ( +
+ {Arrays.fromNumberOfElements(2).map((v, index) => ( + + + + ))} + +
+ ) +} + +CallDistanceEditor.propTypes = CallEditorPropTypes diff --git a/webapp/components/expression/nodes/call/functions.js b/webapp/components/expression/nodes/call/functions.js index a80b14ca97..51b809f842 100644 --- a/webapp/components/expression/nodes/call/functions.js +++ b/webapp/components/expression/nodes/call/functions.js @@ -2,6 +2,7 @@ import * as Expression from '@core/expressionParser/expression' import { CallCategoryItemPropEditor } from './callCategoryItemPropEditor' import { CallCountEditor } from './callCountEditor' +import { CallDistanceEditor } from './callDistanceEditor' import { CallIncludesEditor } from './callIncludesEditor' import { CallIsEmptyEditor } from './callIsEmptyEditor' import { CallIsNotEmptyEditor } from './callIsNotEmptyEditor' @@ -30,6 +31,10 @@ export const functions = { label: 'count(...)', component: CallCountEditor, }, + [functionNames.distance]: { + label: 'distance(...)', + component: CallDistanceEditor, + }, [functionNames.includes]: { label: 'includes(...)', component: CallIncludesEditor,