From bf2b4efbfd6cec003827dae35c645fd807cad0d9 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Tue, 6 Oct 2020 22:17:16 +0530 Subject: [PATCH] Fix for action execution (#1023) --- .../FormWidgets/FormReset_spec.js | 1 - .../propertyControls/ChartDataControl.tsx | 9 ++- app/client/src/widgets/CheckboxWidget.tsx | 15 ++--- app/client/src/widgets/DatePickerWidget.tsx | 15 ++--- app/client/src/widgets/DropdownWidget.tsx | 29 +++++----- app/client/src/widgets/InputWidget.tsx | 15 ++--- app/client/src/widgets/MapWidget.tsx | 32 +++++------ app/client/src/widgets/MetaHOC.tsx | 42 ++++++++++++-- app/client/src/widgets/RadioGroupWidget.tsx | 15 ++--- .../src/widgets/RichTextEditorWidget.tsx | 15 ++--- app/client/src/widgets/TableWidget.tsx | 57 ++++++++----------- app/client/src/widgets/TabsWidget.tsx | 15 ++--- app/client/src/widgets/VideoWidget.tsx | 41 ++++++------- 13 files changed, 149 insertions(+), 152 deletions(-) diff --git a/app/client/cypress/integration/Smoke_TestSuite/FormWidgets/FormReset_spec.js b/app/client/cypress/integration/Smoke_TestSuite/FormWidgets/FormReset_spec.js index eea5f26e11..7e3290ce81 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/FormWidgets/FormReset_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/FormWidgets/FormReset_spec.js @@ -22,7 +22,6 @@ describe("Form reset functionality", function() { cy.get(".tr") .eq(2) - .click() .should("not.have.class", "selected-row"); cy.get(widgetsPage.inputWidget + " " + "input") diff --git a/app/client/src/components/propertyControls/ChartDataControl.tsx b/app/client/src/components/propertyControls/ChartDataControl.tsx index fcd08e00b7..44a90d44d2 100644 --- a/app/client/src/components/propertyControls/ChartDataControl.tsx +++ b/app/client/src/components/propertyControls/ChartDataControl.tsx @@ -257,11 +257,10 @@ class ChartDataControl extends BaseControl { }> = this.props.propertyValue; const updatedChartData = chartData.map((item, i) => { if (index === i) { - if (propertyName === "seriesName") { - item.seriesName = updatedValue; - } else { - item.data = updatedValue; - } + return { + ...item, + [propertyName]: updatedValue, + }; } return item; }); diff --git a/app/client/src/widgets/CheckboxWidget.tsx b/app/client/src/widgets/CheckboxWidget.tsx index cb5447753c..f31369e553 100644 --- a/app/client/src/widgets/CheckboxWidget.tsx +++ b/app/client/src/widgets/CheckboxWidget.tsx @@ -64,15 +64,12 @@ class CheckboxWidget extends BaseWidget { } onCheckChange = (isChecked: boolean) => { - this.props.updateWidgetMetaProperty("isChecked", isChecked); - if (this.props.onCheckChange) { - super.executeAction({ - dynamicString: this.props.onCheckChange, - event: { - type: EventType.ON_CHECK_CHANGE, - }, - }); - } + this.props.updateWidgetMetaProperty("isChecked", isChecked, { + dynamicString: this.props.onCheckChange, + event: { + type: EventType.ON_CHECK_CHANGE, + }, + }); }; getWidgetType(): WidgetType { diff --git a/app/client/src/widgets/DatePickerWidget.tsx b/app/client/src/widgets/DatePickerWidget.tsx index 51dc1ad412..d76833285a 100644 --- a/app/client/src/widgets/DatePickerWidget.tsx +++ b/app/client/src/widgets/DatePickerWidget.tsx @@ -74,15 +74,12 @@ class DatePickerWidget extends BaseWidget { } onDateSelected = (selectedDate: string) => { - this.props.updateWidgetMetaProperty("selectedDate", selectedDate); - if (this.props.onDateSelected) { - super.executeAction({ - dynamicString: this.props.onDateSelected, - event: { - type: EventType.ON_DATE_SELECTED, - }, - }); - } + this.props.updateWidgetMetaProperty("selectedDate", selectedDate, { + dynamicString: this.props.onDateSelected, + event: { + type: EventType.ON_DATE_SELECTED, + }, + }); }; getWidgetType(): WidgetType { diff --git a/app/client/src/widgets/DropdownWidget.tsx b/app/client/src/widgets/DropdownWidget.tsx index 8f6b929d8c..efc008c5d4 100644 --- a/app/client/src/widgets/DropdownWidget.tsx +++ b/app/client/src/widgets/DropdownWidget.tsx @@ -143,6 +143,12 @@ class DropdownWidget extends BaseWidget { this.props.updateWidgetMetaProperty( "selectedOptionValue", selectedOption.value, + { + dynamicString: this.props.onOptionChange, + event: { + type: EventType.ON_OPTION_CHANGE, + }, + }, ); } } else if (this.props.selectionType === "MULTI_SELECT") { @@ -161,16 +167,13 @@ class DropdownWidget extends BaseWidget { this.props.updateWidgetMetaProperty( "selectedOptionValueArr", newSelectedValue, - ); - } - - if (this.props.onOptionChange && isChanged) { - super.executeAction({ - dynamicString: this.props.onOptionChange, - event: { - type: EventType.ON_OPTION_CHANGE, + { + dynamicString: this.props.onOptionChange, + event: { + type: EventType.ON_OPTION_CHANGE, + }, }, - }); + ); } }; @@ -182,15 +185,13 @@ class DropdownWidget extends BaseWidget { this.props.updateWidgetMetaProperty( "selectedOptionValueArr", newSelectedValue, - ); - if (this.props.onOptionChange) { - super.executeAction({ + { dynamicString: this.props.onOptionChange, event: { type: EventType.ON_OPTION_CHANGE, }, - }); - } + }, + ); }; getWidgetType(): WidgetType { diff --git a/app/client/src/widgets/InputWidget.tsx b/app/client/src/widgets/InputWidget.tsx index f34a1b7280..c260a1fc7d 100644 --- a/app/client/src/widgets/InputWidget.tsx +++ b/app/client/src/widgets/InputWidget.tsx @@ -94,18 +94,15 @@ class InputWidget extends BaseWidget { } onValueChange = (value: string) => { - this.props.updateWidgetMetaProperty("text", value); + this.props.updateWidgetMetaProperty("text", value, { + dynamicString: this.props.onTextChanged, + event: { + type: EventType.ON_TEXT_CHANGE, + }, + }); if (!this.props.isDirty) { this.props.updateWidgetMetaProperty("isDirty", true); } - if (this.props.onTextChanged) { - super.executeAction({ - dynamicString: this.props.onTextChanged, - event: { - type: EventType.ON_TEXT_CHANGE, - }, - }); - } }; handleFocusChange = (focusState: boolean) => { diff --git a/app/client/src/widgets/MapWidget.tsx b/app/client/src/widgets/MapWidget.tsx index 5861595a66..bbc94d9758 100644 --- a/app/client/src/widgets/MapWidget.tsx +++ b/app/client/src/widgets/MapWidget.tsx @@ -83,18 +83,19 @@ class MapWidget extends BaseWidget { onCreateMarker = (lat: number, long: number) => { this.disableDrag(true); - this.props.updateWidgetMetaProperty("selectedMarker", { - lat, - long, - }); - if (this.props.onCreateMarker) { - super.executeAction({ + this.props.updateWidgetMetaProperty( + "selectedMarker", + { + lat, + long, + }, + { dynamicString: this.props.onCreateMarker, event: { type: EventType.ON_CREATE_MARKER, }, - }); - } + }, + ); }; onMarkerClick = (lat: number, long: number, title: string) => { @@ -104,15 +105,12 @@ class MapWidget extends BaseWidget { long: long, title: title, }; - this.props.updateWidgetMetaProperty("selectedMarker", selectedMarker); - if (this.props.onMarkerClick) { - super.executeAction({ - dynamicString: this.props.onMarkerClick, - event: { - type: EventType.ON_MARKER_CLICK, - }, - }); - } + this.props.updateWidgetMetaProperty("selectedMarker", selectedMarker, { + dynamicString: this.props.onMarkerClick, + event: { + type: EventType.ON_MARKER_CLICK, + }, + }); }; getPageView() { diff --git a/app/client/src/widgets/MetaHOC.tsx b/app/client/src/widgets/MetaHOC.tsx index 70e96e199d..3fe0c60b8d 100644 --- a/app/client/src/widgets/MetaHOC.tsx +++ b/app/client/src/widgets/MetaHOC.tsx @@ -3,15 +3,26 @@ import BaseWidget, { WidgetProps } from "./BaseWidget"; import _ from "lodash"; import { EditorContext } from "../components/editorComponents/EditorContextProvider"; import { clearPropertyCache } from "../utils/DynamicBindingUtils"; +import { ExecuteActionPayload } from "../constants/ActionConstants"; + +type DebouncedExecuteActionPayload = Omit< + ExecuteActionPayload, + "dynamicString" +> & { dynamicString?: string }; export interface WithMeta { - updateWidgetMetaProperty: (propertyName: string, propertyValue: any) => void; + updateWidgetMetaProperty: ( + propertyName: string, + propertyValue: any, + actionExecution?: DebouncedExecuteActionPayload, + ) => void; } const withMeta = (WrappedWidget: typeof BaseWidget) => { return class MetaHOC extends React.Component { static contextType = EditorContext; updatedProperties = new Map(); + propertyTriggers = new Map(); debouncedHandleUpdateWidgetMetaProperty = _.debounce( this.handleUpdateWidgetMetaProperty.bind(this), @@ -49,20 +60,30 @@ const withMeta = (WrappedWidget: typeof BaseWidget) => { updateWidgetMetaProperty = ( propertyName: string, propertyValue: any, + actionExecution?: DebouncedExecuteActionPayload, ): void => { - this.setState({ - [propertyName]: propertyValue, - }); this.updatedProperties.set(propertyName, true); - this.debouncedHandleUpdateWidgetMetaProperty(); + if (actionExecution) { + this.propertyTriggers.set(propertyName, actionExecution); + } + this.setState( + { + [propertyName]: propertyValue, + }, + () => { + this.debouncedHandleUpdateWidgetMetaProperty(); + }, + ); }; handleUpdateWidgetMetaProperty() { - const { updateWidgetMetaProperty } = this.context; + const { updateWidgetMetaProperty, executeAction } = this.context; const { widgetId, widgetName } = this.props; // We have kept a map of all updated properties. After debouncing we will // go through these properties and update with the final value. This way // we will only update a certain property once per debounce interval. + // Then we will execute any action associated with the trigger of + // that value changing [...this.updatedProperties.keys()].forEach(propertyName => { if (updateWidgetMetaProperty) { const propertyValue = this.state[propertyName]; @@ -70,6 +91,15 @@ const withMeta = (WrappedWidget: typeof BaseWidget) => { updateWidgetMetaProperty(widgetId, propertyName, propertyValue); this.updatedProperties.delete(propertyName); } + const debouncedPayload = this.propertyTriggers.get(propertyName); + if ( + debouncedPayload && + debouncedPayload.dynamicString && + executeAction + ) { + executeAction(debouncedPayload); + this.propertyTriggers.delete(propertyName); + } }); } diff --git a/app/client/src/widgets/RadioGroupWidget.tsx b/app/client/src/widgets/RadioGroupWidget.tsx index f6b83f9c7b..76673ace9d 100644 --- a/app/client/src/widgets/RadioGroupWidget.tsx +++ b/app/client/src/widgets/RadioGroupWidget.tsx @@ -66,15 +66,12 @@ class RadioGroupWidget extends BaseWidget { } onRadioSelectionChange = (updatedValue: string) => { - this.props.updateWidgetMetaProperty("selectedOptionValue", updatedValue); - if (this.props.onSelectionChange) { - super.executeAction({ - dynamicString: this.props.onSelectionChange, - event: { - type: EventType.ON_OPTION_CHANGE, - }, - }); - } + this.props.updateWidgetMetaProperty("selectedOptionValue", updatedValue, { + dynamicString: this.props.onSelectionChange, + event: { + type: EventType.ON_OPTION_CHANGE, + }, + }); }; getWidgetType(): WidgetType { diff --git a/app/client/src/widgets/RichTextEditorWidget.tsx b/app/client/src/widgets/RichTextEditorWidget.tsx index 2b35eb0b9a..c3816c7ac6 100644 --- a/app/client/src/widgets/RichTextEditorWidget.tsx +++ b/app/client/src/widgets/RichTextEditorWidget.tsx @@ -61,15 +61,12 @@ class RichTextEditorWidget extends BaseWidget< } onValueChange = (text: string) => { - this.props.updateWidgetMetaProperty("text", text); - if (this.props.onTextChange) { - super.executeAction({ - dynamicString: this.props.onTextChange, - event: { - type: EventType.ON_TEXT_CHANGE, - }, - }); - } + this.props.updateWidgetMetaProperty("text", text, { + dynamicString: this.props.onTextChange, + event: { + type: EventType.ON_TEXT_CHANGE, + }, + }); }; getPageView() { diff --git a/app/client/src/widgets/TableWidget.tsx b/app/client/src/widgets/TableWidget.tsx index c02907aae8..1f17a2fdb7 100644 --- a/app/client/src/widgets/TableWidget.tsx +++ b/app/client/src/widgets/TableWidget.tsx @@ -570,15 +570,12 @@ class TableWidget extends BaseWidget { const { onSearchTextChanged } = this.props; this.resetSelectedRowIndex(); this.props.updateWidgetMetaProperty("pageNo", 1); - this.props.updateWidgetMetaProperty("searchText", searchKey); - if (onSearchTextChanged) { - super.executeAction({ - dynamicString: onSearchTextChanged, - event: { - type: EventType.ON_SEARCH, - }, - }); - } + this.props.updateWidgetMetaProperty("searchText", searchKey, { + dynamicString: onSearchTextChanged, + event: { + type: EventType.ON_SEARCH, + }, + }); }; updateHiddenColumns = (hiddenColumns?: string[]) => { @@ -596,7 +593,7 @@ class TableWidget extends BaseWidget { }; handleRowClick = (rowData: object, index: number) => { - const { onRowSelected, selectedRowIndices } = this.props; + const { selectedRowIndices } = this.props; if (this.props.multiRowSelection) { if (selectedRowIndices.includes(index)) { const rowIndex = selectedRowIndices.indexOf(index); @@ -619,30 +616,27 @@ class TableWidget extends BaseWidget { this.props.updateWidgetMetaProperty( "selectedRow", this.props.filteredTableData[index], - ); - } - if (onRowSelected) { - super.executeAction({ - dynamicString: onRowSelected, - event: { - type: EventType.ON_ROW_SELECTED, + { + dynamicString: this.props.onRowSelected, + event: { + type: EventType.ON_ROW_SELECTED, + }, }, - }); + ); } }; handleNextPageClick = () => { let pageNo = this.props.pageNo || 1; pageNo = pageNo + 1; - this.props.updateWidgetMetaProperty("pageNo", pageNo); + this.props.updateWidgetMetaProperty("pageNo", pageNo, { + dynamicString: this.props.onPageChange, + event: { + type: EventType.ON_NEXT_PAGE, + }, + }); if (this.props.onPageChange) { this.resetSelectedRowIndex(); - super.executeAction({ - dynamicString: this.props.onPageChange, - event: { - type: EventType.ON_NEXT_PAGE, - }, - }); } }; @@ -655,15 +649,14 @@ class TableWidget extends BaseWidget { let pageNo = this.props.pageNo || 1; pageNo = pageNo - 1; if (pageNo >= 1) { - this.props.updateWidgetMetaProperty("pageNo", pageNo); + this.props.updateWidgetMetaProperty("pageNo", pageNo, { + dynamicString: this.props.onPageChange, + event: { + type: EventType.ON_PREV_PAGE, + }, + }); if (this.props.onPageChange) { this.resetSelectedRowIndex(); - super.executeAction({ - dynamicString: this.props.onPageChange, - event: { - type: EventType.ON_PREV_PAGE, - }, - }); } } }; diff --git a/app/client/src/widgets/TabsWidget.tsx b/app/client/src/widgets/TabsWidget.tsx index cdff94c742..fdb803e561 100644 --- a/app/client/src/widgets/TabsWidget.tsx +++ b/app/client/src/widgets/TabsWidget.tsx @@ -24,15 +24,12 @@ class TabsWidget extends BaseWidget< } onTabChange = (tabId: string) => { - this.props.updateWidgetMetaProperty("selectedTabId", tabId); - if (this.props.onTabSelected) { - super.executeAction({ - dynamicString: this.props.onTabSelected, - event: { - type: EventType.ON_TAB_CHANGE, - }, - }); - } + this.props.updateWidgetMetaProperty("selectedTabId", tabId, { + dynamicString: this.props.onTabSelected, + event: { + type: EventType.ON_TAB_CHANGE, + }, + }); }; static getDerivedPropertiesMap() { diff --git a/app/client/src/widgets/VideoWidget.tsx b/app/client/src/widgets/VideoWidget.tsx index 7e8a9b3e54..d0fae3e6d6 100644 --- a/app/client/src/widgets/VideoWidget.tsx +++ b/app/client/src/widgets/VideoWidget.tsx @@ -68,38 +68,33 @@ class VideoWidget extends BaseWidget { autoplay={autoPlay} controls={true} onPlay={() => { - this.props.updateWidgetMetaProperty("playState", PlayState.PLAYING); - if (onPlay) { - super.executeAction({ + this.props.updateWidgetMetaProperty( + "playState", + PlayState.PLAYING, + { dynamicString: onPlay, event: { type: EventType.ON_VIDEO_PLAY, }, - }); - } + }, + ); }} onPause={() => { //TODO: We do not want the pause event for onSeek or onEnd. - this.props.updateWidgetMetaProperty("playState", PlayState.PAUSED); - if (onPause) { - super.executeAction({ - dynamicString: onPause, - event: { - type: EventType.ON_VIDEO_PAUSE, - }, - }); - } + this.props.updateWidgetMetaProperty("playState", PlayState.PAUSED, { + dynamicString: onPause, + event: { + type: EventType.ON_VIDEO_PAUSE, + }, + }); }} onEnded={() => { - this.props.updateWidgetMetaProperty("playState", PlayState.ENDED); - if (onEnd) { - super.executeAction({ - dynamicString: onEnd, - event: { - type: EventType.ON_VIDEO_END, - }, - }); - } + this.props.updateWidgetMetaProperty("playState", PlayState.ENDED, { + dynamicString: onEnd, + event: { + type: EventType.ON_VIDEO_END, + }, + }); }} />