fix: reset widget to default value after setter method (#29151)

## Description
This PR ensures that widgets are reset to their default value after the
`setValue` setter method is used to set its value

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

#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change
> Please delete options that are not relevant.
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- Chore (housekeeping or task changes that don't impact user perception)
- This change requires a documentation update
>
>
>
## 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**
- Implemented a new reset functionality for widgets, allowing users to
revert to default values after changes.
  - Enhanced widget meta updates with a new reset action.

- **Bug Fixes**
- Added test cases to ensure widget reset functionality works as
expected, even after asynchronous operations.

- **Refactor**
- Refactored evaluation logic to improve handling of widget meta updates
and resets.
  - Improved action execution logic for resetting widget properties.

- **Tests**
- Expanded end-to-end regression tests to cover new reset widget
functionality.

- **Documentation**
- Updated internal documentation to reflect new action types and
evaluation processes related to widget meta updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Druthi Polisetty <druthi@appsmith.com>
This commit is contained in:
Favour Ohanekwu 2023-12-08 11:16:31 +01:00 committed by GitHub
parent 40e7e8b535
commit 95fa2328a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 461 additions and 52 deletions

View File

@ -0,0 +1,83 @@
import {
entityExplorer,
propPane,
draggableWidgets,
agHelper,
deployMode,
locators,
jsEditor,
} from "../../../../support/Objects/ObjectsCore";
describe("Reset widget action", () => {
it("Reset widget to default after setValue has been applied", () => {
entityExplorer.DragDropWidgetNVerify(draggableWidgets.INPUT_V2);
propPane.UpdatePropertyFieldValue("Default value", "John");
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 300, 300);
propPane.EnterJSContext("onClick", `{{Input1.setValue('Hello!')}}`);
propPane.UpdatePropertyFieldValue("Label", "Set value");
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 500, 100);
propPane.EnterJSContext("onClick", `{{resetWidget("Input1")}}`);
propPane.UpdatePropertyFieldValue("Label", "Reset value");
deployMode.DeployApp();
agHelper.ClickButton("Set value");
agHelper.AssertText(
locators._widgetInDeployed(draggableWidgets.INPUT_V2) + " input",
"val",
"Hello!",
);
agHelper.ClickButton("Reset value");
agHelper.AssertText(
locators._widgetInDeployed(draggableWidgets.INPUT_V2) + " input",
"val",
"John",
);
agHelper.ClearNType(
locators._widgetInDeployed(draggableWidgets.INPUT_V2) + " input",
"Testing",
);
agHelper.ClickButton("Reset value");
agHelper.AssertText(
locators._widgetInDeployed(draggableWidgets.INPUT_V2) + " input",
"val",
"John",
);
});
it("Reset value is accessible after 'awaiting'", () => {
deployMode.NavigateBacktoEditor();
agHelper.ClearNType(locators._input, "Meta Text");
const JS_OBJECT_BODY = `export default {
async resetInputWithoutAwait () {
resetWidget('Input1')
showAlert(Input1.text)
},
async resetInputWithAwait () {
await resetWidget('Input1')
showAlert(Input1.text)
}
}`;
// Create js object
jsEditor.CreateJSObject(JS_OBJECT_BODY, {
paste: true,
completeReplace: true,
toRun: false,
prettify: false,
shouldCreateNewJSObj: true,
});
agHelper.Sleep(4000);
jsEditor.SelectFunctionDropdown("resetInputWithoutAwait");
agHelper.ClickButton("Run");
agHelper.AssertContains("Meta Text");
jsEditor.SelectFunctionDropdown("resetInputWithAwait");
agHelper.ClickButton("Run");
agHelper.AssertContains("John");
});
});

View File

@ -55,6 +55,18 @@ export const resetWidgetMetaProperty = (
});
};
export const resetWidgetMetaUpdates = (
evalMetaUpdates: EvalMetaUpdates,
): BatchAction<ResetWidgetMetaPayload> => {
return batchAction({
type: ReduxActionTypes.RESET_WIDGET_META_UPDATES,
payload: {
evalMetaUpdates,
},
postEvalActions: [{ type: ReduxActionTypes.RESET_WIDGET_META_EVALUATED }],
});
};
export const resetChildrenMetaProperty = (
widgetId: string,
): ReduxAction<{ widgetId: string }> => {

View File

@ -90,6 +90,7 @@ export const EVALUATE_REDUX_ACTIONS = [
ReduxActionTypes.SET_META_PROP_AND_EVAL,
ReduxActionTypes.META_UPDATE_DEBOUNCED_EVAL,
ReduxActionTypes.RESET_WIDGET_META,
ReduxActionTypes.RESET_WIDGET_META_UPDATES,
// Batches
ReduxActionTypes.BATCH_UPDATES_SUCCESS,
// App Theme

View File

@ -426,6 +426,7 @@ const ActionTypes = {
META_UPDATE_DEBOUNCED_EVAL: "META_UPDATE_DEBOUNCED_EVAL",
RESET_CHILDREN_WIDGET_META: "RESET_CHILDREN_WIDGET_META",
RESET_WIDGET_META: "RESET_WIDGET_META",
RESET_WIDGET_META_UPDATES: "RESET_WIDGET_META_UPDATES",
RESET_WIDGET_META_EVALUATED: "RESET_WIDGET_META_EVALUATED",
RESET_WIDGETS_META_STATE: "RESET_WIDGETS_META_STATE",
UPDATE_WIDGET_NAME_INIT: "UPDATE_WIDGET_NAME_INIT",

View File

@ -368,7 +368,6 @@ export const generateDataTreeWidget = (
// overridingMetaProps maps properties that can be overriden by either default values or meta changes to initial values.
// initial value is set to metaProps value or defaultMetaProps value.
Object.entries(defaultMetaProps).forEach(([key, value]) => {
if (overridingMetaPropsMap[key]) {
overridingMetaProps[key] =

View File

@ -13,7 +13,11 @@ import {
} from "@appsmith/constants/ReduxActionConstants";
import produce from "immer";
import type { EvalMetaUpdates } from "@appsmith/workers/common/DataTreeEvaluator/types";
import { getMetaWidgetResetObj } from "./metaReducerUtils";
import {
getMetaWidgetResetObj,
getNextMetaStateWithUpdates,
setMetaValuesOnResetFromEval,
} from "./metaReducerUtils";
import type { WidgetEntityConfig } from "@appsmith/entities/DataTree/types";
export type WidgetMetaState = Record<string, unknown>;
@ -28,18 +32,7 @@ export const metaReducer = createReducer(initialState, {
evalMetaUpdates: EvalMetaUpdates;
}>,
) => {
const { evalMetaUpdates } = action.payload;
if (!evalMetaUpdates.length) return state;
// if metaObject is updated in dataTree we also update meta values, to keep meta state in sync.
const newMetaState = produce(state, (draftMetaState) => {
evalMetaUpdates.forEach(({ metaPropertyPath, value, widgetId }) => {
set(draftMetaState, [widgetId, ...metaPropertyPath], value);
});
return draftMetaState;
});
return newMetaState;
return getNextMetaStateWithUpdates(state, action);
},
[ReduxActionTypes.SET_META_PROP]: (
state: MetaState,
@ -132,6 +125,14 @@ export const metaReducer = createReducer(initialState, {
}
return state;
},
[ReduxActionTypes.RESET_WIDGET_META_UPDATES]: (
state: MetaState,
action: ReduxAction<{
evalMetaUpdates: EvalMetaUpdates;
}>,
) => {
return setMetaValuesOnResetFromEval(state, action);
},
[ReduxActionTypes.RESET_WIDGETS_META_STATE]: (
state: MetaState,
action: ReduxAction<{ widgetIdsToClear: string[] }>,

View File

@ -4,7 +4,11 @@ import type {
PropertyOverrideDependency,
} from "@appsmith/entities/DataTree/types";
import { klona } from "klona";
import type { WidgetMetaState } from ".";
import type { MetaState, WidgetMetaState } from ".";
import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import type { EvalMetaUpdates } from "@appsmith/workers/common/DataTreeEvaluator/types";
import produce from "immer";
import { set, unset } from "lodash";
export function getMetaWidgetResetObj(
evaluatedWidget: WidgetEntity | undefined,
@ -30,3 +34,50 @@ export function getMetaWidgetResetObj(
}
return resetMetaObj;
}
/**
* When resetWidget is called from eval, we update all the meta values and remove those meta values which are undefined
*/
export function setMetaValuesOnResetFromEval(
state: MetaState,
action: ReduxAction<{
evalMetaUpdates: EvalMetaUpdates;
}>,
) {
const { evalMetaUpdates } = action.payload;
if (!evalMetaUpdates.length) return state;
const newMetaState = klona(state);
evalMetaUpdates.forEach(({ metaPropertyPath, value, widgetId }) => {
if (value === undefined) {
unset(newMetaState, `${widgetId}.${metaPropertyPath.join(".")}`);
} else {
set(newMetaState, [widgetId, ...metaPropertyPath], value);
}
});
return newMetaState;
}
export function getNextMetaStateWithUpdates(
state: MetaState,
action: ReduxAction<{
evalMetaUpdates: EvalMetaUpdates;
}>,
) {
const { evalMetaUpdates } = action.payload;
if (!evalMetaUpdates.length) return state;
// if metaObject is updated in dataTree we also update meta values, to keep meta state in sync.
const newMetaState = produce(state, (draftMetaState) => {
evalMetaUpdates.forEach(({ metaPropertyPath, value, widgetId }) => {
set(draftMetaState, [widgetId, ...metaPropertyPath], value);
});
return draftMetaState;
});
return newMetaState;
}

View File

@ -1,10 +1,7 @@
import { put, select, take } from "redux-saga/effects";
import { getWidgetByName } from "sagas/selectors";
import {
resetChildrenMetaProperty,
resetWidgetMetaProperty,
} from "actions/metaActions";
import AppsmithConsole from "utils/AppsmithConsole";
import { resetWidgetMetaUpdates } from "actions/metaActions";
import {
ActionValidationError,
TriggerFailureError,
@ -12,20 +9,15 @@ import {
import { getType, Types } from "utils/TypeHelpers";
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { getDataTree, getConfigTree } from "selectors/dataTreeSelectors";
import type {
WidgetEntity,
WidgetEntityConfig,
} from "@appsmith/entities/DataTree/types";
import type { DataTree, ConfigTree } from "entities/DataTree/dataTreeTypes";
import { isWidget } from "@appsmith/workers/Evaluation/evaluationUtils";
import type { TResetWidgetDescription } from "workers/Evaluation/fns/resetWidget";
import AppsmithConsole from "utils/AppsmithConsole";
export default function* resetWidgetActionSaga(
action: TResetWidgetDescription,
) {
const { payload } = action;
const { widgetName } = payload;
const { metaUpdates, widgetName } = payload;
if (getType(widgetName) !== Types.STRING) {
throw new ActionValidationError(
"RESET_WIDGET_META_RECURSIVE_BY_NAME",
@ -34,8 +26,6 @@ export default function* resetWidgetActionSaga(
getType(widgetName),
);
}
const dataTree: DataTree = yield select(getDataTree);
const configTree: ConfigTree = yield select(getConfigTree);
const widget: FlattenedWidgetProps | undefined = yield select(
getWidgetByName,
@ -44,23 +34,10 @@ export default function* resetWidgetActionSaga(
if (!widget) {
throw new TriggerFailureError(`Widget ${payload.widgetName} not found`);
}
const evaluatedEntity = dataTree[widget.widgetName];
const evaluatedEntityConfig = configTree[widget.widgetName];
if (isWidget(evaluatedEntity)) {
yield put(
resetWidgetMetaProperty(
widget.widgetId,
evaluatedEntity as WidgetEntity,
evaluatedEntityConfig as WidgetEntityConfig,
),
);
if (payload.resetChildren) {
yield put(resetChildrenMetaProperty(widget.widgetId));
}
}
yield put(resetWidgetMetaUpdates(metaUpdates));
yield take(ReduxActionTypes.RESET_WIDGET_META_EVALUATED);
AppsmithConsole.info({
text: `resetWidget('${payload.widgetName}', ${payload.resetChildren}) was triggered`,
});

View File

@ -19,6 +19,10 @@ const BATCH_PRIORITY = {
priority: 0,
needsSaga: false,
},
[ReduxActionTypes.RESET_WIDGET_META_UPDATES]: {
priority: 0,
needsSaga: false,
},
[ReduxActionTypes.UPDATE_WIDGET_PROPERTY]: {
priority: 0,
needsSaga: false,

View File

@ -22,7 +22,7 @@ import {
getDataTree,
getUnevaluatedDataTree,
} from "selectors/dataTreeSelectors";
import { getMetaWidgets, getWidgets } from "sagas/selectors";
import { getMetaWidgets, getWidgets, getWidgetsMeta } from "sagas/selectors";
import type { WidgetTypeConfigMap } from "WidgetProvider/factory";
import WidgetFactory from "WidgetProvider/factory";
import { GracefulWorkerService } from "utils/WorkerUtil";
@ -260,6 +260,8 @@ export function* evaluateTreeSaga(
PerformanceTransactionName.DATA_TREE_EVALUATION,
);
const appMode: ReturnType<typeof getAppMode> = yield select(getAppMode);
const widgetsMeta: ReturnType<typeof getWidgetsMeta> =
yield select(getWidgetsMeta);
const evalTreeRequestData: EvalTreeRequestData = {
unevalTree: unEvalAndConfigTree,
@ -271,6 +273,7 @@ export function* evaluateTreeSaga(
forceEvaluation,
metaWidgets,
appMode,
widgetsMeta,
};
const workerResponse: EvalTreeResponseData = yield call(

View File

@ -309,7 +309,6 @@ describe("Add functions", () => {
it("resetWidget works", () => {
const widgetName = "widget1";
const resetChildren = true;
expect(evalContext.resetWidget(widgetName, resetChildren)).resolves.toBe(
{},
);
@ -323,6 +322,7 @@ describe("Add functions", () => {
payload: {
widgetName,
resetChildren,
metaUpdates: [],
},
},
eventType: undefined,

View File

@ -1,22 +1,284 @@
import { promisify } from "./utils/Promisify";
function resetWidgetFnDescriptor(widgetName: string, resetChildren = true) {
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
import {
canvasWidgets,
dataTreeEvaluator,
canvasWidgetsMeta,
} from "../handlers/evalTree";
import _ from "lodash";
import type {
WidgetEntityConfig,
WidgetEntity,
} from "@appsmith/entities/DataTree/types";
import { isWidget } from "@appsmith/workers/Evaluation/evaluationUtils";
import { klona } from "klona";
import { getDynamicBindings, isDynamicValue } from "utils/DynamicBindingUtils";
import evaluateSync from "../evaluate";
import type { DescendantWidgetMap } from "sagas/WidgetOperationUtils";
import type { MetaState } from "reducers/entityReducers/metaReducer";
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
import type { EvalMetaUpdates } from "@appsmith/workers/common/DataTreeEvaluator/types";
import type { DataTree } from "entities/DataTree/dataTreeTypes";
import { validateAndParseWidgetProperty } from "workers/common/DataTreeEvaluator/validationUtils";
function resetWidgetFnDescriptor(
widgetName: string,
resetChildren = true,
metaUpdates: EvalMetaUpdates,
) {
return {
type: "RESET_WIDGET_META_RECURSIVE_BY_NAME" as const,
payload: { widgetName, resetChildren },
payload: { widgetName, resetChildren, metaUpdates },
};
}
export type TResetWidgetArgs = Parameters<typeof resetWidgetFnDescriptor>;
export type TResetWidgetDescription = ReturnType<
typeof resetWidgetFnDescriptor
>;
export type TResetWidgetActionType = TResetWidgetDescription["type"];
async function resetWidget(
...args: Parameters<typeof resetWidgetFnDescriptor>
...args: [widgetName: string, resetChildren: boolean]
) {
return promisify(resetWidgetFnDescriptor)(...args);
const widgetName = args[0];
const resetChildren = args[1] || true;
const metaUpdates: EvalMetaUpdates = [];
const updatedProperties: string[][] = [];
resetWidgetMetaProperty(
widgetName,
resetChildren,
metaUpdates,
updatedProperties,
);
return promisify(resetWidgetFnDescriptor)(
widgetName,
resetChildren,
metaUpdates,
);
}
function resetWidgetMetaProperty(
widgetName: string,
resetChildren = true,
evalMetaUpdates: EvalMetaUpdates,
updatedProperties: string[][],
) {
const widget: FlattenedWidgetProps | undefined = _.find(
Object.values(canvasWidgets || {}),
(widget) => widget.widgetName === widgetName,
);
if (!dataTreeEvaluator || !widget) return;
const evalTree = dataTreeEvaluator.getEvalTree();
const oldUnEvalTree = dataTreeEvaluator.getOldUnevalTree();
const configTree = dataTreeEvaluator.getConfigTree();
const evalProps = dataTreeEvaluator.getEvalProps();
const evalPathsIdenticalToState =
dataTreeEvaluator.getEvalPathsIdenticalToState();
const evaluatedEntity = evalTree[widget.widgetName];
const evaluatedEntityConfig = configTree[
widget.widgetName
] as WidgetEntityConfig;
if (evaluatedEntity && isWidget(evaluatedEntity)) {
const metaObj = evaluatedEntity.meta;
const currentMetaProperties = Object.keys(metaObj);
const { propertyOverrideDependency } = evaluatedEntityConfig;
for (const propertyPath of currentMetaProperties) {
const defaultPropertyPath =
propertyOverrideDependency[propertyPath]?.DEFAULT;
if (defaultPropertyPath) {
const unEvalEntity = oldUnEvalTree[widget.widgetName] as WidgetEntity;
const expressionToEvaluate: string = unEvalEntity[defaultPropertyPath];
let finalValue: unknown;
if (
expressionToEvaluate &&
typeof expressionToEvaluate === "string" &&
isDynamicValue(expressionToEvaluate)
) {
const { jsSnippets } = getDynamicBindings(expressionToEvaluate);
const { result } = evaluateSync(
jsSnippets[0] || expressionToEvaluate,
evalTree,
false,
{},
undefined,
configTree,
);
finalValue = klona(result);
} else {
finalValue = klona(expressionToEvaluate);
}
const parsedValue = validateAndParseWidgetProperty({
fullPropertyPath: `${widget.widgetName}.${defaultPropertyPath}`,
widget: unEvalEntity,
configTree,
evalPropertyValue: finalValue,
unEvalPropertyValue: expressionToEvaluate,
evalProps,
evalPathsIdenticalToState,
});
evalMetaUpdates.push({
widgetId: evaluatedEntity.widgetId,
metaPropertyPath: propertyPath.split("."),
value: parsedValue,
});
continue;
} else {
evalMetaUpdates.push({
widgetId: evaluatedEntity.widgetId,
metaPropertyPath: propertyPath.split("."),
value: undefined,
});
}
}
if (resetChildren) {
resetChildrenMetaProperty(
widget.widgetId,
evalTree,
evalMetaUpdates,
updatedProperties,
);
}
}
}
function sortWidgetsMetaByParent(widgetsMeta: MetaState, parentId: string) {
return _.reduce(
widgetsMeta,
function (
result: {
childrenWidgetsMeta: MetaState;
otherWidgetsMeta: MetaState;
},
currentWidgetMeta,
key,
) {
return key.startsWith(parentId + "_")
? {
...result,
childrenWidgetsMeta: {
...result.childrenWidgetsMeta,
[key]: currentWidgetMeta,
},
}
: {
...result,
otherWidgetsMeta: {
...result.otherWidgetsMeta,
[key]: currentWidgetMeta,
},
};
},
{
childrenWidgetsMeta: {},
otherWidgetsMeta: {},
},
);
}
export function getWidgetDescendantToReset(
canvasWidgets: CanvasWidgetsReduxState,
widgetId: string,
evaluatedDataTree: DataTree,
widgetsMeta: MetaState,
): DescendantWidgetMap[] {
const descendantList: DescendantWidgetMap[] = [];
const widget = _.get(canvasWidgets, widgetId);
const sortedWidgetsMeta = sortWidgetsMetaByParent(widgetsMeta, widgetId);
for (const childMetaWidgetId of Object.keys(
sortedWidgetsMeta.childrenWidgetsMeta,
)) {
const evaluatedChildWidget = _.find(evaluatedDataTree, function (entity) {
return isWidget(entity) && entity.widgetId === childMetaWidgetId;
}) as WidgetEntity | undefined;
descendantList.push({
id: childMetaWidgetId,
evaluatedWidget: evaluatedChildWidget,
});
const grandChildren = getWidgetDescendantToReset(
canvasWidgets,
childMetaWidgetId,
evaluatedDataTree,
sortedWidgetsMeta.otherWidgetsMeta,
);
if (grandChildren.length) {
descendantList.push(...grandChildren);
}
}
if (widget) {
const { children = [] } = widget;
if (children && children.length) {
for (const childIndex in children) {
if (children.hasOwnProperty(childIndex)) {
const childWidgetId = children[childIndex];
const childCanvasWidget = _.get(canvasWidgets, childWidgetId);
const childWidgetName = childCanvasWidget.widgetName;
const childWidget = evaluatedDataTree[childWidgetName];
if (isWidget(childWidget)) {
descendantList.push({
id: childWidgetId,
evaluatedWidget: childWidget,
});
const grandChildren = getWidgetDescendantToReset(
canvasWidgets,
childWidgetId,
evaluatedDataTree,
sortedWidgetsMeta.otherWidgetsMeta,
);
if (grandChildren.length) {
descendantList.push(...grandChildren);
}
}
}
}
}
}
return descendantList;
}
function resetChildrenMetaProperty(
parentWidgetId: string,
evaluatedDataTree: DataTree,
evalMetaUpdates: EvalMetaUpdates,
updatedProperties: string[][],
) {
const childrenList = getWidgetDescendantToReset(
canvasWidgets,
parentWidgetId,
evaluatedDataTree,
canvasWidgetsMeta,
);
for (const childIndex in childrenList) {
const { evaluatedWidget: childWidget } = childrenList[childIndex];
if (!childWidget) continue;
resetWidgetMetaProperty(
childWidget?.widgetName,
false,
evalMetaUpdates,
updatedProperties,
);
}
}
export default resetWidget;

View File

@ -14,6 +14,7 @@ export function promisify<P extends ReadonlyArray<unknown>>(
return async function (...args: P) {
const actionDescription = fnDescriptor(...args);
const metaData = ExecutionMetaData.getExecutionMetaData();
const response = await WorkerMessenger.request({
method: MAIN_THREAD_ACTION.PROCESS_TRIGGER,
data: {

View File

@ -27,9 +27,13 @@ import DataStore from "../dataStore";
import type { TransmissionErrorHandler } from "../fns/utils/Messenger";
import { MessageType, sendMessage } from "utils/MessageUtil";
import { startSpansInAnEvaluation } from "UITelemetry/generateWebWorkerTraces";
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
export let replayMap: Record<string, ReplayEntity<any>> | undefined;
export let dataTreeEvaluator: DataTreeEvaluator | undefined;
export const CANVAS = "canvas";
export let canvasWidgetsMeta: Record<string, any>;
export let canvasWidgets: CanvasWidgetsReduxState;
export default function (request: EvalWorkerSyncRequest) {
const { data } = request;
@ -56,11 +60,15 @@ export default function (request: EvalWorkerSyncRequest) {
theme,
unevalTree: __unevalTree__,
widgets,
widgetsMeta,
widgetTypeConfigMap,
} = data as EvalTreeRequestData;
const unevalTree = __unevalTree__.unEvalTree;
configTree = __unevalTree__.configTree as ConfigTree;
canvasWidgets = widgets;
canvasWidgetsMeta = widgetsMeta;
try {
if (!dataTreeEvaluator) {
isCreateFirstTree = true;

View File

@ -42,6 +42,7 @@ export interface EvalTreeRequestData {
forceEvaluation: boolean;
metaWidgets: MetaWidgetsReduxState;
appMode?: APP_MODE;
widgetsMeta: Record<string, any>;
}
export interface EvalTreeResponseData {

View File

@ -192,6 +192,10 @@ export default class DataTreeEvaluator {
return this.evalTree;
}
getEvalProps() {
return this.evalProps;
}
setEvalTree(evalTree: DataTree) {
this.evalTree = evalTree;
}

View File

@ -74,6 +74,7 @@ export function validateAndParseWidgetProperty({
evalPathsIdenticalToState: EvalPathsIdenticalToState;
}): unknown {
const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath);
if (isPathDynamicTrigger(widget, propertyPath)) {
// TODO find a way to validate triggers
return unEvalPropertyValue;