PromucFlow_constructor/app/client/src/selectors/dataTreeSelectors.ts
Ayush Pahwa d5b711cd5f
feat: workflow js run on browser (#31106)
## Description
This PR introduces browser run for workflows JS files. 
Changes:
- In case of workflows js object, there are no variables in the
definition. This causes the jsaction.variables to be undefined which
causes further issues down the line preventing second API call for
update to the server. Added handling for that.
- Pushed workflows action to the data tree to start with linting and
autocomplete. This was coming as empty for workflows editor.

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

#### Type of change

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

## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [ ] Manual
- [ ] JUnit
- [ ] Jest
- [ ] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## 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/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] 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


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced data selection capabilities to include workflow actions and
JavaScript actions.
- **Bug Fixes**
- Improved stability in JavaScript action handling by ensuring variables
are always defined, preventing potential errors.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-02-26 21:14:35 +05:30

181 lines
5.1 KiB
TypeScript

import { createSelector } from "reselect";
import {
getCurrentActions,
getAppData,
getPluginDependencyConfig,
getPluginEditorConfigs,
getCurrentJSCollections,
getInputsForModule,
getModuleInstances,
getModuleInstanceEntities,
getCurrentModuleActions,
getCurrentModuleJSCollections,
} from "@appsmith/selectors/entitiesSelector";
import type { WidgetEntity } from "@appsmith/entities/DataTree/types";
import type { DataTree } from "entities/DataTree/dataTreeTypes";
import { DataTreeFactory } from "entities/DataTree/dataTreeFactory";
import {
getIsMobileBreakPoint,
getMetaWidgets,
getWidgetsForEval,
getWidgetsMeta,
} from "sagas/selectors";
import "url-search-params-polyfill";
import { getPageList } from "./appViewSelectors";
import type { AppState } from "@appsmith/reducers";
import { getSelectedAppThemeProperties } from "./appThemingSelectors";
import type { LoadingEntitiesState } from "reducers/evaluationReducers/loadingEntitiesReducer";
import _, { get } from "lodash";
import type { EvaluationError } from "utils/DynamicBindingUtils";
import { getEvalErrorPath } from "utils/DynamicBindingUtils";
import ConfigTreeActions from "utils/configTree";
import { DATATREE_INTERNAL_KEYWORDS } from "constants/WidgetValidation";
import { getLayoutSystemType } from "./layoutSystemSelectors";
import {
getCurrentWorkflowActions,
getCurrentWorkflowJSActions,
} from "@appsmith/selectors/workflowSelectors";
export const getLoadingEntities = (state: AppState) =>
state.evaluations.loadingEntities;
/**
* This selector is created to combine a couple of data points required by getUnevaluatedDataTree selector.
* Current version of reselect package only allows upto 12 arguments. Hence, this workaround.
* TODO: Figure out a better way to do this in a separate task. Or update the package if possible.
*/
const getLayoutSystemPayload = createSelector(
getLayoutSystemType,
getIsMobileBreakPoint,
(layoutSystemType, isMobile) => {
return {
layoutSystemType,
isMobile,
};
},
);
const getCurrentActionEntities = createSelector(
getCurrentActions,
getCurrentModuleActions,
getCurrentWorkflowActions,
getCurrentJSCollections,
getCurrentModuleJSCollections,
getCurrentWorkflowJSActions,
(
actions,
moduleActions,
workflowActions,
jsActions,
moduleJSActions,
workflowJsActions,
) => {
return {
actions: [...actions, ...moduleActions, ...workflowActions],
jsActions: [...jsActions, ...moduleJSActions, ...workflowJsActions],
};
},
);
const getModulesData = createSelector(
getInputsForModule,
getModuleInstances,
getModuleInstanceEntities,
(moduleInputs, moduleInstances, moduleInstanceEntities) => {
return {
moduleInputs: moduleInputs,
moduleInstances: moduleInstances,
moduleInstanceEntities: moduleInstanceEntities,
};
},
);
export const getUnevaluatedDataTree = createSelector(
getCurrentActionEntities,
getWidgetsForEval,
getWidgetsMeta,
getPageList,
getAppData,
getPluginEditorConfigs,
getPluginDependencyConfig,
getSelectedAppThemeProperties,
getMetaWidgets,
getLayoutSystemPayload,
getLoadingEntities,
getModulesData,
(
currentActionEntities,
widgets,
widgetsMeta,
pageListPayload,
appData,
editorConfigs,
pluginDependencyConfig,
selectedAppThemeProperty,
metaWidgets,
layoutSystemPayload,
loadingEntities,
modulesData,
) => {
const pageList = pageListPayload || [];
return DataTreeFactory.create({
...currentActionEntities,
widgets,
widgetsMeta,
pageList,
appData,
editorConfigs,
pluginDependencyConfig,
theme: selectedAppThemeProperty,
metaWidgets,
loadingEntities,
...layoutSystemPayload,
...modulesData,
});
},
);
export const getEvaluationInverseDependencyMap = (state: AppState) =>
state.evaluations.dependencies.inverseDependencyMap;
export const getIsWidgetLoading = createSelector(
[getLoadingEntities, (_state: AppState, widgetName: string) => widgetName],
(loadingEntities: LoadingEntitiesState, widgetName: string) =>
loadingEntities.has(widgetName),
);
/**
* returns evaluation tree object
*
* @param state
*/
export const getDataTree = (state: AppState): DataTree =>
state.evaluations.tree;
export const getConfigTree = (): any => {
return ConfigTreeActions.getConfigTree();
};
export const getWidgetEvalValues = createSelector(
[getDataTree, (_state: AppState, widgetName: string) => widgetName],
(tree: DataTree, widgetName: string) => tree[widgetName] as WidgetEntity,
);
// For autocomplete. Use actions cached responses if
// there isn't a response already
export const getDataTreeForAutocomplete = createSelector(
getDataTree,
(tree: DataTree) => {
return _.omit(tree, Object.keys(DATATREE_INTERNAL_KEYWORDS));
},
);
export const getPathEvalErrors = createSelector(
[
getDataTreeForAutocomplete,
(_: unknown, dataTreePath: string) => dataTreePath,
],
(dataTree: DataTree, dataTreePath: string) =>
get(dataTree, getEvalErrorPath(dataTreePath), []) as EvaluationError[],
);