PromucFlow_constructor/app/client/src/plugins/Linting/lintTree.ts
Druthi Polisetty 2fc20cfe8e
feat: widget property setters (#23441)
## Description


- This PR adds setter methods to update widget property
programmatically.

Example:-

`Input1.setText("setter methods are cool!");`

Docs link : 
https://docs.appsmith.com/reference/widgets
For any selected widget check the `Methods` section

#### PR fixes following issue(s)
Fixes 


#### Type of change

- New feature (non-breaking change which adds functionality)

## Testing
>
#### How Has This Been Tested?
- [x] Manual
- [x] Jest
- [x] Cypress
>
>
#### Test Plan
https://github.com/appsmithorg/TestSmith/issues/2409

#### Issues raised during DP testing
- [x] [Errors are not logged in the
debugger](https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1564017346)
separate GitHub issue
https://github.com/appsmithorg/appsmith/issues/24609
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1564155545
( `setVisibility("false")` )
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1580525843
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1576582825
- Blocker for testing
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1577956441
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1577930108
- Not a issue (lint error query)
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1593471791
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1591440488
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1586747864
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1596738201
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1598541537
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1611413076
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1612621567
- [ ]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1619654507
- [ ]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1621256722

>
>
## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change)
have been covered
- [x] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest)
- [x] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed

---------

Co-authored-by: Rishabh Rathod <rishabh.rathod@appsmith.com>
2023-07-08 19:37:26 +05:30

114 lines
3.8 KiB
TypeScript

import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils";
import { get, isEmpty, set } from "lodash";
import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers";
import type { LintError } from "utils/DynamicBindingUtils";
import { globalData } from "./globalData";
import lintBindingPath from "./utils/lintBindingPath";
import lintTriggerPath from "./utils/lintTriggerPath";
import lintJSObjectBody from "./utils/lintJSObjectBody";
import sortLintingPathsByType from "./utils/sortLintingPathsByType";
import lintJSObjectProperty from "./utils/lintJSObjectProperty";
import setters from "workers/Evaluation/setters";
import type {
getLintErrorsFromTreeProps,
getLintErrorsFromTreeResponse,
} from "./types";
export function getLintErrorsFromTree({
asyncJSFunctionsInDataFields,
cloudHosting,
configTree,
jsPropertiesState,
pathsToLint,
unEvalTree,
}: getLintErrorsFromTreeProps): getLintErrorsFromTreeResponse {
const lintTreeErrors: LintErrorsStore = {};
const lintedJSPaths = new Set<string>();
setters.init(configTree, unEvalTree);
globalData.initialize(unEvalTree, configTree, cloudHosting);
const { bindingPaths, jsObjectPaths, triggerPaths } = sortLintingPathsByType(
pathsToLint,
unEvalTree,
configTree,
);
// Lint binding paths
bindingPaths.forEach((bindingPath) => {
const { entityName } = getEntityNameAndPropertyPath(bindingPath);
const entity = unEvalTree[entityName];
const unEvalPropertyValue = get(
unEvalTree,
bindingPath,
) as unknown as string;
const lintErrors = lintBindingPath({
dynamicBinding: unEvalPropertyValue,
entity,
fullPropertyPath: bindingPath,
globalData: globalData.getGlobalData(false),
});
set(lintTreeErrors, `["${bindingPath}"]`, lintErrors);
});
// Lint TriggerPaths
triggerPaths.forEach((triggerPath) => {
const { entityName } = getEntityNameAndPropertyPath(triggerPath);
const entity = unEvalTree[entityName];
const unEvalPropertyValue = get(
unEvalTree,
triggerPath,
) as unknown as string;
// remove all lint errors from path
set(lintTreeErrors, `["${triggerPath}"]`, []);
const lintErrors = lintTriggerPath({
userScript: unEvalPropertyValue,
entity,
globalData: globalData.getGlobalData(true),
});
set(lintTreeErrors, `["${triggerPath}"]`, lintErrors);
});
// Lint jsobject paths
if (jsObjectPaths.size) {
jsObjectPaths.forEach((jsObjectPath) => {
const { entityName: jsObjectName, propertyPath: jsPropertyName } =
getEntityNameAndPropertyPath(jsObjectPath);
const jsObjectState = get(jsPropertiesState, jsObjectName);
const jsObjectBodyPath = `["${jsObjectName}.body"]`;
// An empty state shows that there is a parse error in the jsObject or the object is empty, so we lint the entire body
// instead of an individual properties
if (isEmpty(jsObjectState)) {
lintedJSPaths.add(`${jsObjectName}.body`);
const jsObjectBodyLintErrors = lintJSObjectBody(
jsObjectName,
globalData.getGlobalData(true),
);
set(lintTreeErrors, jsObjectBodyPath, jsObjectBodyLintErrors);
} else if (jsPropertyName !== "body") {
lintedJSPaths.add(jsObjectPath);
const propertyLintErrors = lintJSObjectProperty(
jsObjectPath,
jsObjectState,
asyncJSFunctionsInDataFields,
);
const currentLintErrorsInBody = get(
lintTreeErrors,
jsObjectBodyPath,
[] as LintError[],
);
const updatedLintErrors = [
...currentLintErrorsInBody,
...propertyLintErrors,
];
set(lintTreeErrors, jsObjectBodyPath, updatedLintErrors);
}
});
}
return {
errors: lintTreeErrors,
lintedJSPaths: Array.from(lintedJSPaths),
};
}