fix: reset meta to default value (#14468)

* fix: [WIP] reset meta to default value

* refactor

* fix reset child widget and type in metaReducer

* Fix type and refactor test

* fix multiselect click

* Add jest test for reset widget action

* Add cypress test

* Add comments

* Add more cases as per comment

* remove `only` from test case

* Add default value case of array with values

* MultiSelect spec fix

* fix currencyInput reset

* refactor test code suggested in comments

* fix type

* fix more type

* fix cypress test

Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
Rishabh Rathod 2022-06-25 11:00:54 +05:30 committed by GitHub
parent fcbcec751d
commit 5625784829
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 877 additions and 485 deletions

View File

@ -1,312 +1,432 @@
{
"dsl": {
"widgetName": "MainContainer",
"backgroundColor": "none",
"rightColumn": 966,
"snapColumns": 64,
"detachFromLayout": true,
"widgetId": "0",
"dsl": {
"widgetName": "MainContainer",
"backgroundColor": "none",
"rightColumn": 966,
"snapColumns": 64,
"detachFromLayout": true,
"widgetId": "0",
"topRow": 0,
"bottomRow": 5016,
"containerStyle": "none",
"snapRows": 125,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": true,
"version": 59,
"minHeight": 360,
"parentColumnSpace": 1,
"dynamicBindingPathList": [],
"leftColumn": 0,
"children": [
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"backgroundColor": "#FFFFFF",
"widgetName": "Container3",
"rightColumn": 60,
"orientation": "VERTICAL",
"snapColumns": 16,
"widgetId": "jaftzrmtin",
"containerStyle": "card",
"topRow": 0,
"bottomRow": 5016,
"containerStyle": "none",
"snapRows": 125,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": true,
"version": 29,
"minHeight": 360,
"parentColumnSpace": 1,
"bottomRow": 80,
"parentRowSpace": 38,
"isVisible": true,
"type": "CONTAINER_WIDGET",
"version": 1,
"isLoading": false,
"parentColumnSpace": 75.25,
"dynamicBindingPathList": [],
"leftColumn": 0,
"borderRadius": "0px",
"children": [
{
"backgroundColor": "#FFFFFF",
"widgetName": "Container3",
"rightColumn": 60,
"orientation": "VERTICAL",
"snapColumns": 16,
"widgetId": "jaftzrmtin",
"containerStyle": "card",
"boxShadow": "none",
"widgetName": "7hf8kkvvgv",
"topRow": 0,
"bottomRow": 790,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": false,
"minHeight": 800,
"parentColumnSpace": 1,
"dynamicTriggerPathList": [],
"leftColumn": 0,
"dynamicBindingPathList": [],
"children": [
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "Text1",
"rightColumn": 10,
"dynamicPropertyPathList": [],
"widgetId": "4d8d2eh4xg",
"topRow": 0,
"bottomRow": 80,
"bottomRow": 3,
"parentRowSpace": 38,
"isVisible": true,
"type": "CONTAINER_WIDGET",
"version": 1,
"type": "TEXT_WIDGET",
"parentId": "hjiybwqair",
"isLoading": false,
"parentColumnSpace": 75.25,
"parentColumnSpace": 71.75,
"overflow": "SCROLL",
"fontFamily": "System Default",
"dynamicBindingPathList": [],
"leftColumn": 1,
"borderRadius": "0px",
"text": "Test text",
"textStyle": "HEADING"
},
{
"labelTextSize": "0.875rem",
"isRequired": false,
"boxShadow": "none",
"widgetName": "Input1",
"rightColumn": 20,
"widgetId": "i9cuq42zmc",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"topRow": 4,
"bottomRow": 8,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "INPUT_WIDGET_V2",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"resetOnSubmit": false,
"leftColumn": 0,
"children": [
{
"backgroundColor": "transparent",
"widgetName": "7hf8kkvvgv",
"rightColumn": 4816,
"orientation": "VERTICAL",
"snapColumns": 16,
"detachFromLayout": true,
"widgetId": "e3tq9qwta6",
"containerStyle": "none",
"topRow": 0,
"bottomRow": 2128,
"parentRowSpace": 1,
"isVisible": true,
"type": "CANVAS_WIDGET",
"canExtend": false,
"version": 1,
"isLoading": false,
"minHeight": 800,
"parentColumnSpace": 1,
"dynamicTriggerPathList": [],
"leftColumn": 0,
"dynamicBindingPathList": [],
"children": [
{
"widgetName": "Text1",
"rightColumn": 10,
"widgetId": "4d8d2eh4xg",
"dynamicPropertyPathList": [],
"topRow": 0,
"bottomRow": 3,
"parentRowSpace": 38,
"isVisible": true,
"type": "TEXT_WIDGET",
"dynamicBindingPathList": [],
"shouldScroll": true,
"parentId": "hjiybwqair",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 1,
"text": "Test text",
"textStyle": "HEADING"
},
{
"isRequired": false,
"widgetName": "Input1",
"rightColumn": 20,
"widgetId": "i9cuq42zmc",
"topRow": 4,
"bottomRow": 8,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "INPUT_WIDGET_V2",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"resetOnSubmit": false,
"leftColumn": 0,
"dynamicBindingPathList": [],
"inputType": "TEXT",
"isDisabled": false
},
{
"isRequired": false,
"widgetName": "Dropdown1",
"rightColumn": 60,
"isFilterable": true,
"widgetId": "nl5sy9cuaa",
"topRow": 4,
"bottomRow": 8,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "SELECT_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [],
"options": "",
"isDisabled": false
},
{
"widgetName": "Button1",
"rightColumn": 12,
"isDefaultClickDisabled": true,
"widgetId": "gn6ug210ef",
"buttonStyle": "PRIMARY_BUTTON",
"topRow": 16,
"bottomRow": 20,
"parentRowSpace": 38,
"isVisible": true,
"type": "BUTTON_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 4,
"dynamicBindingPathList": [],
"text": "Submit",
"isDisabled": false
},
{
"isRequired": false,
"widgetName": "Checkbox1",
"rightColumn": 52,
"widgetId": "szjhneuog5",
"topRow": 16,
"bottomRow": 20,
"parentRowSpace": 38,
"isVisible": true,
"label": "Label",
"type": "CHECKBOX_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [],
"defaultCheckedState": true,
"isDisabled": false
},
{
"widgetName": "Switch1",
"rightColumn": 52,
"widgetId": "szjhneuog9",
"topRow": 72,
"bottomRow": 76,
"parentRowSpace": 38,
"isVisible": true,
"label": "Switch",
"type": "SWITCH_WIDGET",
"defaultSwitchState": true,
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [],
"isDisabled": false
},
{
"isRequired": false,
"widgetName": "RadioGroup1",
"rightColumn": 12,
"widgetId": "nb2usgp3hv",
"topRow": 28,
"bottomRow": 36,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "RADIO_GROUP_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"defaultOptionValue": "1",
"parentColumnSpace": 71.75,
"leftColumn": 0,
"dynamicBindingPathList": [],
"options": [
{
"label": "Male",
"value": "M"
},
{
"label": "Female",
"value": "F"
}
],
"isDisabled": false
},
{
"widgetName": "DatePicker1",
"defaultDate": "2020-06-03T12:05:44.699+05:30",
"rightColumn": 60,
"dateFormat": "DD/MM/YYYY",
"widgetId": "kyrvcdcm4e",
"topRow": 28,
"bottomRow": 32,
"parentRowSpace": 38,
"isVisible": true,
"datePickerType": "DATE_PICKER",
"label": "",
"type": "DATE_PICKER_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"dynamicTriggerPathList": [
{
"key": "onDateSelected"
}
],
"leftColumn": 40,
"dynamicBindingPathList": [],
"isDisabled": false,
"onDateSelected": "{{showModal()}}"
},
{
"isRequired": false,
"widgetName": "FilePicker1",
"rightColumn": 56,
"isDefaultClickDisabled": true,
"widgetId": "ca22py6vlv",
"topRow": 44,
"bottomRow": 48,
"parentRowSpace": 38,
"isVisible": true,
"label": "Select Files",
"allowedFileTypes": [],
"type": "FILE_PICKER_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 67.1171875,
"leftColumn": 40,
"dynamicBindingPathList": [],
"files": [],
"isDisabled": false
},
{
"widgetName": "RichTextEditor1",
"rightColumn": 32,
"isDefaultClickDisabled": true,
"widgetId": "2uvezzlkn5",
"topRow": 44,
"bottomRow": 64,
"parentRowSpace": 38,
"isVisible": true,
"type": "RICH_TEXT_EDITOR_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 67.1171875,
"leftColumn": 0,
"dynamicBindingPathList": [],
"defaultText": "",
"inputType": "html",
"isDisabled": false
},
{
"isRequired": false,
"widgetName": "MultiSelect2",
"rightColumn": 62,
"widgetId": "p6qkmj8uo1",
"topRow": 49,
"bottomRow": 60,
"parentRowSpace": 10,
"isVisible": true,
"label": "",
"type": "MULTI_SELECT_WIDGET_V2",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"defaultOptionValue": [],
"parentColumnSpace": 13.662109375,
"dynamicTriggerPathList": [],
"leftColumn": 37,
"dynamicBindingPathList": [],
"options": "",
"placeholderText": "select option(s)",
"isDisabled": false
}
]
}
]
"dynamicBindingPathList": [{ "key": "accentColor" }],
"borderRadius": "0px",
"inputType": "TEXT",
"isDisabled": false
},
{
"labelTextSize": "0.875rem",
"isRequired": false,
"boxShadow": "none",
"widgetName": "Dropdown1",
"rightColumn": 60,
"isFilterable": true,
"widgetId": "nl5sy9cuaa",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"topRow": 4,
"bottomRow": 8,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "SELECT_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [{ "key": "accentColor" }],
"borderRadius": "0px",
"options": "",
"isDisabled": false
},
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "Button1",
"rightColumn": 12,
"isDefaultClickDisabled": true,
"buttonColor": "#03B365",
"widgetId": "gn6ug210ef",
"topRow": 16,
"bottomRow": 20,
"parentRowSpace": 38,
"isVisible": true,
"type": "BUTTON_WIDGET",
"version": 1,
"recaptchaType": "V3",
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 4,
"dynamicBindingPathList": [],
"borderRadius": "0px",
"buttonVariant": "PRIMARY",
"text": "Submit",
"isDisabled": false
},
{
"boxShadow": "none",
"widgetName": "Checkbox1",
"topRow": 16,
"bottomRow": 20,
"parentRowSpace": 38,
"type": "CHECKBOX_WIDGET",
"alignWidget": "LEFT",
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [],
"labelPosition": "Right",
"isDisabled": false,
"labelTextSize": "0.875rem",
"isRequired": false,
"rightColumn": 52,
"widgetId": "szjhneuog5",
"accentColor": "#03B365",
"isVisible": true,
"label": "Label",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"borderRadius": "0px",
"defaultCheckedState": true
},
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "Switch1",
"rightColumn": 52,
"widgetId": "szjhneuog9",
"accentColor": "#03B365",
"topRow": 73,
"bottomRow": 77,
"parentRowSpace": 38,
"isVisible": true,
"label": "Switch",
"type": "SWITCH_WIDGET",
"defaultSwitchState": true,
"version": 1,
"parentId": "e3tq9qwta6",
"alignWidget": "LEFT",
"isLoading": false,
"parentColumnSpace": 71.75,
"leftColumn": 40,
"dynamicBindingPathList": [],
"borderRadius": "0px",
"labelPosition": "Right",
"isDisabled": false
},
{
"labelTextSize": "0.875rem",
"isRequired": false,
"boxShadow": "none",
"widgetName": "RadioGroup1",
"rightColumn": 12,
"widgetId": "nb2usgp3hv",
"topRow": 28,
"bottomRow": 36,
"parentRowSpace": 38,
"isVisible": true,
"label": "",
"type": "RADIO_GROUP_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"defaultOptionValue": "1",
"parentColumnSpace": 71.75,
"leftColumn": 0,
"dynamicBindingPathList": [],
"borderRadius": "0px",
"options": [
{ "label": "Male", "value": "M" },
{ "label": "Female", "value": "F" }
],
"isDisabled": false,
"alignment": "left"
},
{
"boxShadow": "none",
"widgetName": "DatePicker1",
"dateFormat": "DD/MM/YYYY",
"topRow": 28,
"bottomRow": 32,
"parentRowSpace": 38,
"type": "DATE_PICKER_WIDGET",
"parentColumnSpace": 71.75,
"dynamicTriggerPathList": [
{ "key": "onDateSelected" }
],
"leftColumn": 40,
"dynamicBindingPathList": [],
"isDisabled": false,
"onDateSelected": "{{showModal()}}",
"labelTextSize": "0.875rem",
"defaultDate": "2020-06-03T12:05:44.699+05:30",
"rightColumn": 60,
"widgetId": "kyrvcdcm4e",
"isVisible": true,
"datePickerType": "DATE_PICKER",
"label": "",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"borderRadius": "0px"
},
{
"labelTextSize": "0.875rem",
"isRequired": false,
"boxShadow": "none",
"widgetName": "FilePicker1",
"rightColumn": 56,
"isDefaultClickDisabled": true,
"widgetId": "ca22py6vlv",
"topRow": 44,
"bottomRow": 48,
"parentRowSpace": 38,
"isVisible": true,
"label": "Select Files",
"allowedFileTypes": [],
"type": "FILE_PICKER_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 67.1171875,
"leftColumn": 40,
"dynamicBindingPathList": [],
"borderRadius": "0px",
"files": [],
"isDisabled": false
},
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "RichTextEditor1",
"rightColumn": 32,
"isDefaultClickDisabled": true,
"widgetId": "2uvezzlkn5",
"topRow": 44,
"bottomRow": 64,
"parentRowSpace": 38,
"isVisible": true,
"type": "RICH_TEXT_EDITOR_WIDGET",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"parentColumnSpace": 67.1171875,
"leftColumn": 0,
"dynamicBindingPathList": [],
"borderRadius": "0px",
"defaultText": "",
"inputType": "html",
"isDisabled": false
},
{
"boxShadow": "none",
"widgetName": "MultiSelect2",
"topRow": 49,
"bottomRow": 60,
"parentRowSpace": 10,
"type": "MULTI_SELECT_WIDGET_V2",
"defaultOptionValue": "",
"parentColumnSpace": 13.662109375,
"dynamicTriggerPathList": [],
"leftColumn": 37,
"dynamicBindingPathList": [{ "key": "accentColor" }],
"options": "",
"placeholderText": "",
"isDisabled": false,
"labelTextSize": "0.875rem",
"isRequired": false,
"rightColumn": 62,
"widgetId": "p6qkmj8uo1",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"isVisible": true,
"label": "",
"version": 1,
"parentId": "e3tq9qwta6",
"isLoading": false,
"borderRadius": "0px"
},
{
"boxShadow": "none",
"widgetName": "Button2",
"onClick": "{{resetWidget('MultiSelect2')}}",
"buttonColor": "{{appsmith.theme.colors.primaryColor}}",
"dynamicPropertyPathList": [{ "key": "onClick" }],
"displayName": "Button",
"iconSVG": "/static/media/icon.cca02633.svg",
"topRow": 68,
"bottomRow": 72,
"parentRowSpace": 10,
"type": "BUTTON_WIDGET",
"hideCard": false,
"animateLoading": true,
"parentColumnSpace": 18.49609375,
"dynamicTriggerPathList": [{ "key": "onClick" }],
"leftColumn": 41,
"dynamicBindingPathList": [
{ "key": "buttonColor" },
{ "key": "borderRadius" }
],
"text": "Reset MultiSelect",
"isDisabled": false,
"key": "sv7prcomh7",
"isDeprecated": false,
"rightColumn": 58,
"isDefaultClickDisabled": true,
"widgetId": "tzstqq5xjt",
"isVisible": true,
"recaptchaType": "V3",
"version": 1,
"parentId": "e3tq9qwta6",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"buttonVariant": "PRIMARY",
"placement": "CENTER"
},
{
"widgetName": "Text2",
"displayName": "Text",
"iconSVG": "/static/media/icon.97c59b52.svg",
"topRow": 60,
"bottomRow": 68,
"parentRowSpace": 10,
"type": "TEXT_WIDGET",
"hideCard": false,
"animateLoading": true,
"overflow": "NONE",
"fontFamily": "{{appsmith.theme.fontFamily.appFont}}",
"parentColumnSpace": 18.49609375,
"dynamicTriggerPathList": [],
"leftColumn": 37,
"dynamicBindingPathList": [
{ "key": "fontFamily" },
{ "key": "borderRadius" },
{ "key": "text" }
],
"shouldTruncate": false,
"truncateButtonColor": "#FFC13D",
"text": "{{MultiSelect2.selectedOptionValues.toString()}}",
"key": "a4y7w4uxvg",
"isDeprecated": false,
"rightColumn": 62,
"textAlign": "LEFT",
"widgetId": "6mabocqffh",
"isVisible": true,
"fontStyle": "BOLD",
"textColor": "#231F20",
"version": 1,
"parentId": "e3tq9qwta6",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"fontSize": "1rem"
}
],
"labelTextSize": "0.875rem",
"backgroundColor": "transparent",
"rightColumn": 4816,
"orientation": "VERTICAL",
"snapColumns": 16,
"detachFromLayout": true,
"widgetId": "e3tq9qwta6",
"containerStyle": "none",
"isVisible": true,
"version": 1,
"isLoading": false,
"borderRadius": "0px"
}
]
}
]
}
}

View File

@ -1,24 +1,12 @@
const explorer = require("../../../../locators/explorerlocators.json");
const testdata = require("../../../../fixtures/testdata.json");
const apiwidget = require("../../../../locators/apiWidgetslocator.json");
import apiEditor from "../../../../locators/ApiEditor";
const WIDGET = {
INPUT_WIDGET_V2: "inputwidgetv2",
TEXT: "textwidget",
PHONE_INPUT_WIDGET: "phoneinputwidget",
CURRENCY_INPUT_WIDGET: "currencyinputwidget",
BUTTON_WIDGET: "buttonwidget",
};
const PROPERTY_SELECTOR = {
onClick: ".t--property-control-onclick",
onSubmit: ".t--property-control-onsubmit",
text: ".t--property-control-text",
};
const getWidgetSelector = (widget) => `.t--widget-${widget}`;
const getWidgetInputSelector = (widget) => `.t--widget-${widget} input`;
import {
WIDGET,
PROPERTY_SELECTOR,
getWidgetSelector,
getWidgetInputSelector,
} from "../../../../locators/WidgetLocators";
const widgetsToTest = {
[WIDGET.INPUT_WIDGET_V2]: {

View File

@ -1,118 +0,0 @@
const commonlocators = require("../../../../locators/commonlocators.json");
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
const widgetLocators = require("../../../../locators/Widgets.json");
const publish = require("../../../../locators/publishWidgetspage.json");
const dsl = require("../../../../fixtures/multiSelectDsl.json");
const pages = require("../../../../locators/Pages.json");
const data = require("../../../../fixtures/example.json");
describe("MultiSelect Widget Functionality", function() {
before(() => {
cy.addDsl(dsl);
});
it("Selects value with invalid default value", () => {
cy.openPropertyPane("multiselectwidgetv2");
cy.testJsontext("options", JSON.stringify(data.input));
cy.testJsontext("defaultvalue", "{{ undefined }}");
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-search-input")
.first()
.focus({ force: true })
.type("{uparrow}", { force: true });
cy.get(".multi-select-dropdown")
.contains("Option 3")
.click({ force: true });
cy.wait(2000);
//Validating option inside multiselect widget
cy.get(".rc-select-selection-item-content")
.first()
.should("have.text", "Option 3");
});
it("Dropdown Functionality To Check Allow select all option", function() {
// select all option is not enable
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-item-content")
.first()
.should("not.have.text", "Select all");
// enable select all option from property pane
cy.openPropertyPane("multiselectwidgetv2");
cy.togglebar(commonlocators.allowSelectAllCheckbox);
// press select all option
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-search-input")
.first()
.focus({ force: true })
.type("{uparrow}", { force: true });
cy.get(".multi-select-dropdown")
.contains("Select all")
.click({ force: true });
cy.wait(2000);
//Validating option inside multiselect widget
cy.get(".rc-select-selection-item-content")
.eq(0)
.should("have.text", "Option 1");
cy.get(".rc-select-selection-item-content")
.eq(1)
.should("have.text", "Option 2");
});
it("Check isDirty meta property", function() {
cy.openPropertyPane("textwidget");
cy.updateCodeInput(".t--property-control-text", `{{MultiSelect2.isDirty}}`);
// Init isDirty by changing defaultOptionValue
cy.openPropertyPane("multiselectwidgetv2");
cy.updateCodeInput(
".t--property-control-defaultvalue",
'[\n {\n "label": "Option 1",\n "value": "1"\n }\n]',
);
cy.get(".t--widget-textwidget").should("contain", "false");
// Interact with UI
cy.get(".rc-select-selector").click({ force: true });
cy.dropdownMultiSelectDynamic("Option 2");
// Check if isDirty is set to true
cy.get(".t--widget-textwidget").should("contain", "true");
// Reset isDirty by changing defaultOptionValue
cy.updateCodeInput(
".t--property-control-defaultvalue",
'[\n {\n "label": "Option 2",\n "value": "2"\n }\n]',
);
// Check if isDirty is set to false
cy.get(".t--widget-textwidget").should("contain", "false");
});
it("Selects value with enter in default value", () => {
cy.updateCodeInput(
".t--property-control-defaultvalue",
'[\n {\n "label": "Option 3",\n "value": "3"\n }\n]',
);
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-item-content")
.first()
.should("have.text", "Option 3");
});
it("Dropdown Functionality To Validate Options", function() {
cy.get(".rc-select-selector").click({ force: true });
cy.dropdownMultiSelectDynamic("Option 2");
});
it("Dropdown Functionality To Unchecked Visible Widget", function() {
cy.togglebarDisable(commonlocators.visibleCheckbox);
cy.PublishtheApp();
cy.get(publish.multiselectwidgetv2 + " " + ".rc-select-selector").should(
"not.exist",
);
cy.get(publish.backToEditor).click();
});
it("Dropdown Functionality To Check Visible Widget", function() {
cy.openPropertyPane("multiselectwidgetv2");
cy.togglebar(commonlocators.visibleCheckbox);
cy.PublishtheApp();
cy.get(publish.multiselectwidgetv2 + " " + ".rc-select-selector").should(
"be.visible",
);
cy.get(publish.backToEditor).click();
});
});
afterEach(() => {
// put your clean up code if any
});

View File

@ -0,0 +1,232 @@
/// <reference types="Cypress" />
const commonlocators = require("../../../../locators/commonlocators.json");
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
const publish = require("../../../../locators/publishWidgetspage.json");
const dsl = require("../../../../fixtures/multiSelectDsl.json");
import data from "../../../../fixtures/example.json";
import {
PROPERTY_SELECTOR,
WIDGET,
getWidgetSelector,
} from "../../../../locators/WidgetLocators";
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
const agHelper = ObjectsRegistry.AggregateHelper,
jsEditor = ObjectsRegistry.JSEditor;
describe("MultiSelect Widget Functionality", function() {
before(() => {
cy.addDsl(dsl);
});
it("1. Selects value with invalid default value", () => {
cy.openPropertyPane("multiselectwidgetv2");
cy.testJsontext("options", JSON.stringify(data.input));
cy.testJsontext("defaultvalue", "{{ undefined }}");
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-search-input")
.first()
.focus({ force: true })
.type("{uparrow}", { force: true });
cy.dropdownMultiSelectDynamic("Option 3");
cy.wait(2000);
//Validating option inside multiselect widget
cy.get(".rc-select-selection-item-content")
.first()
.should("have.text", "Option 3");
});
it("2. Selects value with enter in default value", () => {
cy.testJsontext(
"defaultvalue",
'[\n {\n "label": "Option 3",\n "value": "3"\n }\n]',
);
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-item-content")
.first()
.should("have.text", "Option 3");
});
it("3. Dropdown Functionality To Validate Options", function() {
cy.get(".rc-select-selector").click({ force: true });
cy.dropdownMultiSelectDynamic("Option 2");
});
it("4. Dropdown Functionality To Check Allow select all option", function() {
// select all option is not enable
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-item-content")
.first()
.should("not.have.text", "Select all");
// enable select all option from property pane
cy.openPropertyPane("multiselectwidgetv2");
cy.togglebar(commonlocators.allowSelectAllCheckbox);
// press select all option
cy.get(formWidgetsPage.multiselectwidgetv2)
.find(".rc-select-selection-search-input")
.first()
.focus({ force: true })
.type("{uparrow}", { force: true });
cy.dropdownMultiSelectDynamic("Select all");
cy.wait(3000);
//Validating option inside multiselect widget
cy.get(".rc-select-selection-item-content")
.eq(0)
.should("have.text", "Option 1");
cy.get(".rc-select-selection-item-content")
.eq(1)
.should("have.text", "Option 2");
});
it("5. Check isDirty meta property", function() {
cy.openPropertyPane(WIDGET.TEXT);
cy.updateCodeInput(PROPERTY_SELECTOR.text, `{{MultiSelect2.isDirty}}`);
// Init isDirty by changing defaultOptionValue
cy.openPropertyPane("multiselectwidgetv2");
cy.updateCodeInput(
PROPERTY_SELECTOR.defaultValue,
'[\n {\n "label": "Option 1",\n "value": "1"\n }\n]',
);
cy.get(getWidgetSelector(WIDGET.TEXT))
.eq(0)
.should("contain", "false");
// Interact with UI
cy.get(".rc-select-selector").click({ force: true });
cy.dropdownMultiSelectDynamic("Option 2");
// Check if isDirty is set to true
cy.get(getWidgetSelector(WIDGET.TEXT))
.eq(0)
.should("contain", "true");
// Reset isDirty by changing defaultOptionValue
cy.updateCodeInput(
PROPERTY_SELECTOR.defaultValue,
'[\n {\n "label": "Option 2",\n "value": "2"\n }\n]',
);
// Check if isDirty is set to false
cy.get(getWidgetSelector(WIDGET.TEXT))
.eq(0)
.should("contain", "false");
});
const resetTestCases = [
{
options: [
{ label: "RED", value: "RED" },
{ label: "GREEN", value: "GREEN" },
{ label: "YELLOW", value: "YELLOW" },
],
defaultValue: [{ label: "RED", value: "RED" }],
optionsToSelect: ["GREEN", "YELLOW"],
optionsToDeselect: ["RED"],
},
{
options: [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
{ label: "3", value: "3" },
],
defaultValue: ["1", "2", "3", "4"],
optionsToSelect: [],
optionsToDeselect: ["1"],
},
{
options: [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
{ label: "3", value: "3" },
],
defaultValue: [],
optionsToSelect: [],
optionsToDeselect: [],
},
{
options: [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
{ label: "3", value: "3" },
],
defaultValue: [{ label: "4", value: "4" }],
optionsToSelect: [],
optionsToDeselect: [],
},
];
it("6. Verify MultiSelect resets to default value", function() {
resetTestCases.forEach((testCase) => {
const {
defaultValue,
options,
optionsToDeselect,
optionsToSelect,
} = testCase;
cy.openPropertyPane("multiselectwidgetv2");
// set options
jsEditor.EnterJSContext("Options", JSON.stringify(options));
cy.get("body").type("{esc}");
// set default value
jsEditor.EnterJSContext(
"Default Value",
JSON.stringify(defaultValue, null, 2),
);
// select other options
agHelper.SelectFromMultiSelect(optionsToSelect);
agHelper.RemoveMultiSelectItems(optionsToDeselect);
// reset multiselect
cy.get(
`${getWidgetSelector("buttonwidget")}:contains('Reset MultiSelect')`,
).click();
// verify value is equal to default value
const defaultValuesStringifiedArray = defaultValue
.map((opt) => (opt?.value !== undefined ? opt.value : opt))
.toString();
cy.get(getWidgetSelector("textwidget"))
.eq(1)
.should("have.text", defaultValuesStringifiedArray);
});
});
it("7. Verify MultiSelect deselection behavior", function() {
cy.openPropertyPane("multiselectwidgetv2");
// set options
jsEditor.EnterJSContext(
"Options",
JSON.stringify([{ label: "RED", value: "RED" }]),
);
cy.get("body").type("{esc}");
jsEditor.EnterJSContext("Default Value", '["RED"]');
agHelper.RemoveMultiSelectItems(["RED"]);
// verify value is equal to default value
cy.get(getWidgetSelector("textwidget"))
.eq(1)
.should("have.text", "");
});
it("8. Dropdown Functionality To Unchecked Visible Widget", function() {
cy.togglebarDisable(commonlocators.visibleCheckbox);
cy.PublishtheApp();
cy.get(publish.multiselectwidgetv2 + " " + ".rc-select-selector").should(
"not.exist",
);
cy.get(publish.backToEditor).click();
});
it("9. Dropdown Functionality To Check Visible Widget", function() {
cy.openPropertyPane("multiselectwidgetv2");
cy.togglebar(commonlocators.visibleCheckbox);
cy.PublishtheApp();
cy.get(publish.multiselectwidgetv2 + " " + ".rc-select-selector").should(
"be.visible",
);
cy.get(publish.backToEditor).click();
});
});

View File

@ -0,0 +1,20 @@
export const WIDGET = {
INPUT_WIDGET_V2: "inputwidgetv2",
TEXT: "textwidget",
PHONE_INPUT_WIDGET: "phoneinputwidget",
CURRENCY_INPUT_WIDGET: "currencyinputwidget",
BUTTON_WIDGET: "buttonwidget",
} as const;
export const PROPERTY_SELECTOR = {
onClick: ".t--property-control-onclick",
onSubmit: ".t--property-control-onsubmit",
text: ".t--property-control-text",
defaultValue: ".t--property-control-defaultvalue",
};
type ValueOf<T> = T[keyof T];
export const getWidgetSelector = (widget: ValueOf<typeof WIDGET>) =>
`.t--widget-${widget}`;
export const getWidgetInputSelector = (widget: ValueOf<typeof WIDGET>) =>
`.t--widget-${widget} input`;

View File

@ -45,8 +45,8 @@ export class CommonLocators {
_jsToggle = (controlToToggle: string) => ".t--property-control-" + controlToToggle + " .t--js-toggle"
_spanButton = (btnVisibleText: string) => "//span[text()='" + btnVisibleText + "']/parent::button"
_selectPropDropdown = (ddName: string) => "//div[contains(@class, 't--property-control-" + ddName + "')]//button[contains(@class, 't--open-dropdown-Select-Action')]"
_dropDownValue = (ddOption: string) => ".single-select:contains('" + ddOption + "')"
_selectOptionValue = (ddOption: string) => ".menu-item-link:contains('" + ddOption + "')"
_dropDownValue = (dropdownOption: string) => ".single-select:contains('" + dropdownOption + "')"
_selectOptionValue = (dropdownOption: string) => ".menu-item-link:contains('" + dropdownOption + "')"
_selectedDropdownValue = "//button[contains(@class, 'select-button')]/span[@class='bp3-button-text']"
_actionTextArea = (actionName: string) => "//label[text()='" + actionName + "']/following-sibling::div//div[contains(@class, 'CodeMirror')]//textarea"
_existingDefaultTextInput = ".t--property-control-defaulttext .CodeMirror-code"

View File

@ -47,7 +47,6 @@ export class AggregateHelper {
dsl: string,
elementToCheckPresenceaftDslLoad: string | "" = "",
) {
let currentURL;
let pageid: string;
let layoutId;
cy.url().then((url) => {
@ -221,15 +220,15 @@ export class AggregateHelper {
);
}
public SelectPropertiesDropDown(endpoint: string, ddOption: string) {
public SelectPropertiesDropDown(endpoint: string, dropdownOption: string) {
cy.xpath(this.locator._selectPropDropdown(endpoint))
.first()
.scrollIntoView()
.click();
cy.get(this.locator._dropDownValue(ddOption)).click();
cy.get(this.locator._dropDownValue(dropdownOption)).click();
}
public SelectDropDown(ddOption: string, endpoint: string = "selectwidget") {
public SelectDropDown(dropdownOption: string, endpoint = "selectwidget") {
const mode = window.localStorage.getItem("inDeployedMode");
if (mode == "false") {
cy.xpath(this.locator._selectWidgetDropdown(endpoint))
@ -243,17 +242,22 @@ export class AggregateHelper {
.click();
}
if (endpoint == "selectwidget")
cy.get(this.locator._selectOptionValue(ddOption)).click({ force: true });
else cy.get(this.locator._dropDownValue(ddOption)).click({ force: true });
cy.get(this.locator._selectOptionValue(dropdownOption)).click({
force: true,
});
else
cy.get(this.locator._dropDownValue(dropdownOption)).click({
force: true,
});
this.Sleep(); //for selected value to reflect!
}
public SelectFromDropDown(
ddOption: string,
dropdownOption: string,
insideParent = "",
index = 0,
endpoint: string = "dropdownwidget",
endpoint = "dropdownwidget",
) {
const mode = window.localStorage.getItem("inDeployedMode");
//cy.log("mode frm deployed is:" + mode)
@ -269,14 +273,14 @@ export class AggregateHelper {
.eq(index)
.scrollIntoView()
.click();
cy.get(this.locator._dropDownValue(ddOption)).click({ force: true });
cy.get(this.locator._dropDownValue(dropdownOption)).click({ force: true });
this.Sleep(); //for selected value to reflect!
}
public SelectDropdownList(ddName: string, ddOption: string) {
public SelectDropdownList(ddName: string, dropdownOption: string) {
this.GetNClick(this.locator._existingFieldTextByName(ddName));
cy.get(this.locator._dropdownText)
.contains(ddOption)
.contains(dropdownOption)
.click();
}
@ -284,12 +288,24 @@ export class AggregateHelper {
options: string[],
index = 0,
check = true,
endpoint: string = "multiselectwidgetv2",
endpoint = "multiselectwidgetv2",
) {
cy.get(this.locator._widgetInDeployed(endpoint) + " div.rc-select-selector")
.eq(index)
.scrollIntoView()
.click();
.then(($element: any) => {
// here, we try to click on downArrow in dropdown of multiSelect.
// the position is calculated from top left of the element
const dropdownCenterPosition = +$element.height / 2;
const dropdownArrowApproxPosition = +$element.width - 10;
cy.get($element).click(
dropdownArrowApproxPosition,
dropdownCenterPosition,
{
force: true,
},
);
});
if (check) {
options.forEach(($each) => {

View File

@ -83,12 +83,12 @@ export class DeployMode {
.wait(500);
}
public SelectJsonFormDropDown(ddOption: string, index = 0) {
public SelectJsonFormDropDown(dropdownOption: string, index = 0) {
cy.get(this._jsonSelectDropdown)
.eq(index)
.scrollIntoView()
.click();
cy.get(this.locator._selectOptionValue(ddOption)).click({ force: true });
cy.get(this.locator._selectOptionValue(dropdownOption)).click({ force: true });
this.agHelper.Sleep(); //for selected value to reflect!
}
}

View File

@ -4,6 +4,7 @@ import {
} from "@appsmith/constants/ReduxActionConstants";
import { BatchAction, batchAction } from "actions/batchActions";
import { EvalMetaUpdates } from "workers/DataTreeEvaluator/types";
import { DataTreeWidget } from "../entities/DataTree/dataTreeFactory";
export interface UpdateWidgetMetaPropertyPayload {
widgetId: string;
@ -26,13 +27,20 @@ export const updateWidgetMetaPropAndEval = (
});
};
export type ResetWidgetMetaPayload = {
widgetId: string;
evaluatedWidget: DataTreeWidget;
};
export const resetWidgetMetaProperty = (
widgetId: string,
): BatchAction<{ widgetId: string }> => {
evaluatedWidget: DataTreeWidget,
): BatchAction<ResetWidgetMetaPayload> => {
return batchAction({
type: ReduxActionTypes.RESET_WIDGET_META,
payload: {
widgetId,
evaluatedWidget,
},
postEvalActions: [{ type: ReduxActionTypes.RESET_WIDGET_META_EVALUATED }],
});

View File

@ -1,6 +1,9 @@
import { set } from "lodash";
import { createReducer } from "utils/AppsmithUtils";
import { UpdateWidgetMetaPropertyPayload } from "actions/metaActions";
import {
UpdateWidgetMetaPropertyPayload,
ResetWidgetMetaPayload,
} from "actions/metaActions";
import {
ReduxActionTypes,
@ -9,8 +12,10 @@ import {
} from "@appsmith/constants/ReduxActionConstants";
import produce from "immer";
import { EvalMetaUpdates } from "workers/DataTreeEvaluator/types";
import { klona } from "klona";
export type MetaState = Record<string, Record<string, unknown>>;
export type WidgetMetaState = Record<string, unknown>;
export type MetaState = Record<string, WidgetMetaState>;
export const initialState: MetaState = {};
@ -93,11 +98,31 @@ export const metaReducer = createReducer(initialState, {
},
[ReduxActionTypes.RESET_WIDGET_META]: (
state: MetaState,
action: ReduxAction<{ widgetId: string }>,
action: ReduxAction<ResetWidgetMetaPayload>,
) => {
const widgetId = action.payload.widgetId;
const { evaluatedWidget, widgetId } = action.payload;
if (widgetId in state) {
return { ...state, [widgetId]: {} };
// only reset widgets whose meta properties were changed.
// reset widget: sets the meta values to current default values of widget
const resetMetaObj: WidgetMetaState = {};
// evaluatedWidget is widget data inside dataTree, this will have latest default values of widget
if (evaluatedWidget) {
const { propertyOverrideDependency } = evaluatedWidget;
// propertyOverrideDependency has defaultProperty name for each meta property of widget
Object.entries(propertyOverrideDependency).map(
([propertyName, dependency]) => {
const defaultPropertyValue =
dependency.DEFAULT && evaluatedWidget[dependency.DEFAULT];
if (defaultPropertyValue !== undefined) {
// cloning data to avoid mutation
resetMetaObj[propertyName] = klona(defaultPropertyValue);
}
},
);
}
return { ...state, [widgetId]: resetMetaObj };
}
return state;
},

View File

@ -5,7 +5,7 @@ import {
ReduxActionTypes,
} from "@appsmith/constants/ReduxActionConstants";
let previousState = initialState;
let currentMetaState = initialState;
const inputWidget = {
widgetId: "incwlne",
@ -21,13 +21,13 @@ const noAction = (): ReduxAction<unknown> => {
};
test("should return the initial state", () => {
expect(metaReducer(undefined, noAction())).toEqual(previousState);
expect(metaReducer(undefined, noAction())).toEqual(currentMetaState);
});
test("Add a widget meta values", () => {
previousState = initialState;
currentMetaState = initialState;
expect(
metaReducer(previousState, {
metaReducer(currentMetaState, {
type: ReduxActionTypes.SET_META_PROP,
payload: {
widgetId: inputWidget.widgetId,
@ -51,28 +51,70 @@ test("Update widget meta state using evalMetaUpdates", () => {
value: ["YELLOW"],
},
];
const newMetaReducerState = metaReducer(
previousState,
currentMetaState = metaReducer(
currentMetaState,
updateMetaState(evalMetaUpdates),
);
expect(newMetaReducerState).toEqual({
expect(currentMetaState).toEqual({
incwlne: {
text: "test123",
selectedValues: ["YELLOW"],
},
});
previousState = newMetaReducerState;
});
test("Reset widget", () => {
expect(
metaReducer(previousState, {
describe("Reset widget meta action", () => {
test("Reset widget with only widgetId", () => {
currentMetaState = metaReducer(currentMetaState, {
type: ReduxActionTypes.RESET_WIDGET_META,
payload: {
widgetId: inputWidget.widgetId,
},
});
expect(currentMetaState).toEqual({
incwlne: {},
});
});
currentMetaState = initialState;
expect(
metaReducer(currentMetaState, {
type: ReduxActionTypes.SET_META_PROP,
payload: {
widgetId: inputWidget.widgetId,
propertyName: inputWidget.propertyName,
propertyValue: inputWidget.propertyValue,
},
}),
).toEqual({
incwlne: {},
incwlne: {
selectedValues: ["GREEN", "BLUE", "YELLOW"],
},
});
test("Reset widget with evaluated values", () => {
expect(
metaReducer(currentMetaState, {
type: ReduxActionTypes.RESET_WIDGET_META,
payload: {
widgetId: inputWidget.widgetId,
evaluatedWidget: {
defaultSelectedValues: ["GREEN"],
selectedValues: ["GREEN", "BLUE", "YELLOW"],
widgetId: inputWidget.widgetId,
propertyOverrideDependency: {
selectedValues: {
DEFAULT: "defaultSelectedValues",
META: "meta.selectedValues",
},
},
},
},
}),
).toEqual({
incwlne: {
selectedValues: ["GREEN"],
},
});
});
});

View File

@ -16,6 +16,9 @@ import {
import { getType, Types } from "utils/TypeHelpers";
import { FlattenedWidgetProps } from "widgets/constants";
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { getDataTree } from "selectors/dataTreeSelectors";
import { DataTree } from "entities/DataTree/dataTreeFactory";
import { isWidget } from "workers/evaluationUtils";
export default function* resetWidgetActionSaga(
payload: ResetWidgetDescription["payload"],
@ -29,6 +32,7 @@ export default function* resetWidgetActionSaga(
getType(widgetName),
);
}
const dataTree: DataTree = yield select(getDataTree);
const widget: FlattenedWidgetProps | undefined = yield select(
getWidgetByName,
@ -37,10 +41,12 @@ export default function* resetWidgetActionSaga(
if (!widget) {
throw new TriggerFailureError(`Widget ${payload.widgetName} not found`);
}
yield put(resetWidgetMetaProperty(widget.widgetId));
if (payload.resetChildren) {
yield put(resetChildrenMetaProperty(widget.widgetId));
const evaluatedEntity = dataTree[widget.widgetName];
if (isWidget(evaluatedEntity)) {
yield put(resetWidgetMetaProperty(widget.widgetId, evaluatedEntity));
if (payload.resetChildren) {
yield put(resetChildrenMetaProperty(widget.widgetId));
}
}
yield take(ReduxActionTypes.RESET_WIDGET_META_EVALUATED);

View File

@ -173,7 +173,7 @@ function* evaluateTreeSaga(
if (evalMetaUpdates.length) {
yield put(updateMetaState(evalMetaUpdates));
}
log.debug({ evalMetaUpdates });
log.debug({ evalMetaUpdatesLength: evalMetaUpdates.length });
const updatedDataTree: DataTree = yield select(getDataTree);
log.debug({ jsUpdates: jsUpdates });

View File

@ -701,15 +701,20 @@ const unsetPropertyPath = (obj: Record<string, unknown>, path: string) => {
};
function* resetChildrenMetaSaga(action: ReduxAction<{ widgetId: string }>) {
const parentWidgetId = action.payload.widgetId;
const { widgetId: parentWidgetId } = action.payload;
const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const childrenIds: string[] = getWidgetChildren(
const evaluatedDataTree: DataTree = yield select(getDataTree);
const childrenList = getWidgetChildren(
canvasWidgets,
parentWidgetId,
evaluatedDataTree,
);
for (const childIndex in childrenIds) {
const childId = childrenIds[childIndex];
yield put(resetWidgetMetaProperty(childId));
for (const childIndex in childrenList) {
const { evaluatedWidget: childWidget, id: childId } = childrenList[
childIndex
];
yield put(resetWidgetMetaProperty(childId, childWidget));
}
}

View File

@ -51,6 +51,8 @@ import {
import { getWidgetSpacesSelectorForContainer } from "selectors/editorSelectors";
import { reflow } from "reflow";
import { getBottomRowAfterReflow } from "utils/reflowHookUtils";
import { DataTreeWidget } from "entities/DataTree/dataTreeFactory";
import { isWidget } from "../workers/evaluationUtils";
export interface CopiedWidgetGroup {
widgetId: string;
@ -270,8 +272,7 @@ export const handleSpecificCasesWhilePasting = (
return widgets;
};
export function getWidgetChildren(
export function getWidgetChildrenIds(
canvasWidgets: CanvasWidgetsReduxState,
widgetId: string,
): any {
@ -289,7 +290,7 @@ export function getWidgetChildren(
if (children.hasOwnProperty(childIndex)) {
const child = children[childIndex];
childrenIds.push(child);
const grandChildren = getWidgetChildren(canvasWidgets, child);
const grandChildren = getWidgetChildrenIds(canvasWidgets, child);
if (grandChildren.length) {
childrenIds.push(...grandChildren);
}
@ -299,6 +300,54 @@ export function getWidgetChildren(
return childrenIds;
}
export type ChildrenWidgetMap = { id: string; evaluatedWidget: DataTreeWidget };
/**
* getWidgetChildren: It gets all the child widgets of given widget's id with evaluated values
*
*/
export function getWidgetChildren(
canvasWidgets: CanvasWidgetsReduxState,
widgetId: string,
evaluatedDataTree: DataTree,
): ChildrenWidgetMap[] {
const childrenList: ChildrenWidgetMap[] = [];
const widget = _.get(canvasWidgets, widgetId);
// When a form widget tries to resetChildrenMetaProperties
// But one or more of its container like children
// have just been deleted, widget can be undefined
if (widget === undefined) {
return [];
}
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)) {
childrenList.push({
id: childWidgetId,
evaluatedWidget: childWidget,
});
const grandChildren = getWidgetChildren(
canvasWidgets,
childWidgetId,
evaluatedDataTree,
);
if (grandChildren.length) {
childrenList.push(...grandChildren);
}
}
}
}
}
return childrenList;
}
export const getParentWidgetIdForPasting = function*(
widgets: CanvasWidgetsReduxState,
selectedWidget: FlattenedWidgetProps | undefined,
@ -387,7 +436,7 @@ export const getSelectedWidgetIfPastingIntoListWidget = function(
selectedWidget.children &&
selectedWidget?.type === "LIST_WIDGET"
) {
const childrenIds: string[] = getWidgetChildren(
const childrenIds: string[] = getWidgetChildrenIds(
canvasWidgets,
selectedWidget.children[0],
);

View File

@ -29,7 +29,7 @@ import {
CanvasWidgetsReduxState,
FlattenedWidgetProps,
} from "reducers/entityReducers/canvasWidgetsReducer";
import { getWidgetChildren } from "./WidgetOperationUtils";
import { getWidgetChildrenIds } from "./WidgetOperationUtils";
import { AppState } from "reducers";
import { checkIsDropTarget } from "components/designSystems/appsmith/PositionedContainer";
import WidgetFactory from "utils/WidgetFactory";
@ -140,7 +140,7 @@ function* getAllSelectableChildren() {
: false;
if (selectGrandChildren) {
allChildren = yield call(
getWidgetChildren,
getWidgetChildrenIds,
canvasWidgets,
lastSelectedWidget,
);

View File

@ -233,7 +233,7 @@ class CurrencyInputWidget extends BaseInputWidget<
try {
const formattedValue = formatCurrencyNumber(
this.props.decimals,
String(this.props.value),
this.props.text,
);
this.props.updateWidgetMetaProperty("text", formattedValue);
} catch (e) {

View File

@ -531,7 +531,6 @@ class MultiSelectWidget extends BaseWidget<
static getDefaultPropertiesMap(): Record<string, string> {
return {
selectedOptions: "defaultOptionValue",
filterText: "",
};
}