diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index ea1b7b490d..c1f21e8571 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -480,9 +480,7 @@ class CodeEditor extends Component { [], ) as EvaluationError[]; - let annotations: Annotation[] = []; - - annotations = getLintAnnotations(editor.getValue(), errors); + const annotations = getLintAnnotations(editor.getValue(), errors); this.updateLintingCallback(editor, annotations); } @@ -593,7 +591,8 @@ class CodeEditor extends Component { this.state.isFocused && !hideEvaluatedValue && ("evaluatedValue" in this.props || - ("dataTreePath" in this.props && !!this.props.dataTreePath)); + ("dataTreePath" in this.props && !!dataTreePath)); + return ( { type: "Function", autocompleteDataType: AutocompleteDataType.FUNCTION, }; - delete config.dataTreePath; delete config.evaluatedValue; } diff --git a/app/client/src/workers/DataTreeEvaluator.ts b/app/client/src/workers/DataTreeEvaluator.ts index d430a3f0c9..a383d71085 100644 --- a/app/client/src/workers/DataTreeEvaluator.ts +++ b/app/client/src/workers/DataTreeEvaluator.ts @@ -53,9 +53,15 @@ import { EXECUTION_PARAM_REFERENCE_REGEX, } from "constants/AppsmithActionConstants/ActionConstants"; import { DATA_BIND_REGEX } from "constants/BindingsConstants"; -import evaluate, { EvalResult } from "workers/evaluate"; +import evaluate, { + createGlobalData, + EvalResult, + EvaluationScriptType, + getScriptToEval, +} from "workers/evaluate"; import { substituteDynamicBindingWithValues } from "workers/evaluationSubstitution"; import { Severity } from "entities/AppsmithConsole"; +import { getLintingErrors } from "workers/lint"; export default class DataTreeEvaluator { dependencyMap: DependencyMap = {}; @@ -373,7 +379,8 @@ export default class DataTreeEvaluator { } } if (isWidget(entity)) { - // Set default property dependency + // Make property dependant on the default property as any time the default changes + // the property needs to change const defaultProperties = this.widgetConfigMap[entity.type] .defaultProperties; Object.entries(defaultProperties).forEach( @@ -383,6 +390,13 @@ export default class DataTreeEvaluator { ]; }, ); + // Adding the dynamic triggers in the dependency list as they need linting whenever updated + // we dont make it dependant on anything else + if (entity.dynamicTriggerPathList) { + Object.values(entity.dynamicTriggerPathList).forEach(({ key }) => { + dependencies[`${entityName}.${key}`] = []; + }); + } } if (isAction(entity)) { Object.entries(entity.dependencyMap).forEach( @@ -442,9 +456,13 @@ export default class DataTreeEvaluator { const isABindingPath = (isAction(entity) || isWidget(entity)) && isPathADynamicBinding(entity, propertyPath); + const isATriggerPath = + isWidget(entity) && isPathADynamicTrigger(entity, propertyPath); let evalPropertyValue; const requiresEval = - isABindingPath && isDynamicValue(unEvalPropertyValue); + isABindingPath && + !isATriggerPath && + isDynamicValue(unEvalPropertyValue); if (propertyPath) { _.set(currentTree, getEvalErrorPath(fullPropertyPath), []); } @@ -475,8 +493,7 @@ export default class DataTreeEvaluator { } else { evalPropertyValue = unEvalPropertyValue; } - - if (isWidget(entity)) { + if (isWidget(entity) && !isATriggerPath) { const widgetEntity = entity; const defaultPropertyMap = this.widgetConfigMap[widgetEntity.type] .defaultProperties; @@ -508,6 +525,10 @@ export default class DataTreeEvaluator { return _.set(currentTree, fullPropertyPath, parsedValue); } return _.set(currentTree, fullPropertyPath, evalPropertyValue); + } else if (isATriggerPath) { + const errors = this.lintTriggerPath(evalPropertyValue, entity); + addErrorToEntityProperty(errors, currentTree, fullPropertyPath); + return currentTree; } else if (isAction(entity)) { const safeEvaluatedValue = removeFunctions(evalPropertyValue); _.set( @@ -1319,6 +1340,25 @@ export default class DataTreeEvaluator { clearLogs() { this.logs = []; } + + private lintTriggerPath(userScript: string, entity: DataTreeEntity) { + const { jsSnippets } = getDynamicBindings(userScript, entity); + const script = getScriptToEval( + jsSnippets[0], + EvaluationScriptType.TRIGGERS, + ); + const GLOBAL_DATA = createGlobalData( + this.evalTree, + this.resolvedFunctions, + true, + ); + return getLintingErrors( + script, + GLOBAL_DATA, + jsSnippets[0], + EvaluationScriptType.TRIGGERS, + ); + } } const extractReferencesFromBinding = ( diff --git a/app/client/src/workers/evaluate.ts b/app/client/src/workers/evaluate.ts index 602ce685ab..ed44056b36 100644 --- a/app/client/src/workers/evaluate.ts +++ b/app/client/src/workers/evaluate.ts @@ -6,12 +6,11 @@ import { unsafeFunctionForEval, } from "utils/DynamicBindingUtils"; import unescapeJS from "unescape-js"; -import { JSHINT as jshint } from "jshint"; import { Severity } from "entities/AppsmithConsole"; -import { Position } from "codemirror"; import { AppsmithPromise, enhanceDataTreeWithFunctions } from "./Actions"; import { ActionDescription } from "entities/DataTree/actionTriggers"; -import { isEmpty, last } from "lodash"; +import { isEmpty } from "lodash"; +import { getLintingErrors } from "workers/lint"; export type EvalResult = { result: any; @@ -25,7 +24,7 @@ export enum EvaluationScriptType { TRIGGERS = "TRIGGERS", } -const evaluationScriptsPos: Record = { +export const EvaluationScripts: Record = { [EvaluationScriptType.EXPRESSION]: ` function closedFunction () { const result = <