diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/Invalid_binding_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/Invalid_binding_spec.js index 08df6c72d9..52979dc47a 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/Invalid_binding_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/Invalid_binding_spec.js @@ -2,6 +2,7 @@ const testdata = require("../../../../fixtures/testdata.json"); import { entityExplorer, agHelper, + propPane, } from "../../../../support/Objects/ObjectsCore"; describe("Binding the multiple widgets and validating default data", function () { @@ -11,6 +12,7 @@ describe("Binding the multiple widgets and validating default data", function () it("1. Dropdown widget test with invalid binding value", function () { entityExplorer.SelectEntityByName("Dropdown1"); + propPane.ToggleJSMode("sourcedata"); cy.testJsontext("sourcedata", JSON.stringify(testdata.defaultdataBinding)); cy.evaluateErrorMessage(testdata.dropdownErrorMsg); //Table widget test with invalid binding value diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/Widgets_Default_data_validation_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/Widgets_Default_data_validation_spec.js index 545a8b83c3..590b0f0f6c 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/Widgets_Default_data_validation_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/Widgets_Default_data_validation_spec.js @@ -20,6 +20,7 @@ describe("Binding the multiple widgets and validating default data", function () ); //Dropdown widget test with default value from table widget entityExplorer.SelectEntityByName("Dropdown1"); + propPane.ToggleJSMode("sourcedata"); cy.testJsontext( "sourcedata", JSON.stringify(testdata.deafultDropDownWidget), diff --git a/app/client/cypress/e2e/Regression/ClientSide/Debugger/Widget_property_navigation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Debugger/Widget_property_navigation_spec.ts index 3e1398190d..0148c0811d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Debugger/Widget_property_navigation_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Debugger/Widget_property_navigation_spec.ts @@ -147,7 +147,10 @@ describe("excludeForAirgap", "Widget property navigation", () => { ); _.agHelper.GetNClick(OneClickBindingLocator.searchableColumn); _.agHelper.GetNClick( - OneClickBindingLocator.searchableColumnDropdownOption(), + OneClickBindingLocator.columnDropdownOption( + "searchableColumn", + "imdb_id", + ), ); _.agHelper.GetNClick(OneClickBindingLocator.connectData); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/mongoDB_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/mongoDB_spec.ts new file mode 100644 index 0000000000..cc4cd90908 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/mongoDB_spec.ts @@ -0,0 +1,97 @@ +import oneClickBindingLocator from "../../../../../locators/OneClickBindingLocator"; +import { OneClickBinding } from "../spec_utility"; +import { + agHelper, + entityExplorer, + dataSources, + draggableWidgets, + assertHelper, + propPane, +} from "../../../../../support/Objects/ObjectsCore"; +import formWidgetsPage from "../../../../../locators/FormWidgets.json"; +import widgetsPage from "../../../../../locators/Widgets.json"; +import commonlocators from "../../../../../locators/commonlocators.json"; + +const oneClickBinding = new OneClickBinding(); + +describe("Table widget one click binding feature", () => { + it("should check that queries are created and bound to table widget properly", () => { + entityExplorer.DragDropWidgetNVerify( + draggableWidgets.MULTISELECT, + 450, + 200, + ); + + entityExplorer.NavigateToSwitcher("Explorer"); + + dataSources.CreateDataSource("Mongo"); + + cy.get("@dsName").then((dsName) => { + entityExplorer.NavigateToSwitcher("Widgets"); + + entityExplorer.SelectEntityByName("MultiSelect1", "Widgets"); + + oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "netflix", { + label: "name", + value: "director", + }); + }); + + agHelper.GetNClick(oneClickBindingLocator.connectData); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT, 450, 500); + + propPane.UpdatePropertyFieldValue( + "Text", + `{{MultiSelect1.selectedOptionLabels.toString()}}:{{MultiSelect1.selectedOptionValues.toString()}}`, + ); + + [ + { + label: "I Care a Lot", + text: "I Care a Lot:J Blakeson", + }, + { + label: "tick, tick...BOOM!", + text: "I Care a Lot,tick, tick...BOOM!:J Blakeson,Lin-Manuel Miranda", + }, + { + label: "Munich – The Edge of War", + text: "I Care a Lot,tick, tick...BOOM!,Munich – The Edge of War:J Blakeson,Lin-Manuel Miranda,Christian Schwochow", + }, + ].forEach((d) => { + cy.get(formWidgetsPage.multiSelectWidget) + .find(".rc-select-selector") + .click({ + force: true, + }); + + cy.get(".rc-select-item").contains(d.label).click({ + force: true, + }); + cy.get(commonlocators.TextInside).first().should("have.text", d.text); + }); + + agHelper.Sleep(2000); + + cy.get(formWidgetsPage.multiselectWidgetv2search) + .first() + .focus({ force: true } as any) + .type("Haunting", { force: true }); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + cy.get( + ".rc-select-item-option:contains('The Haunting of Hill House')", + ).should("have.length", 1); + cy.get(".rc-select-item") + .contains("The Haunting of Hill House") + .should("exist"); + }); +}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/postgres_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/postgres_spec.ts new file mode 100644 index 0000000000..f129d72269 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/MultiSelectWidget/postgres_spec.ts @@ -0,0 +1,104 @@ +import oneClickBindingLocator from "../../../../../locators/OneClickBindingLocator"; +import { OneClickBinding } from "../spec_utility"; +import { + agHelper, + entityExplorer, + dataSources, + draggableWidgets, + assertHelper, + propPane, +} from "../../../../../support/Objects/ObjectsCore"; +import formWidgetsPage from "../../../../../locators/FormWidgets.json"; +import widgetsPage from "../../../../../locators/Widgets.json"; +import commonlocators from "../../../../../locators/commonlocators.json"; + +const oneClickBinding = new OneClickBinding(); + +describe("Table widget one click binding feature", () => { + it("should check that queries are created and bound to table widget properly", () => { + entityExplorer.DragDropWidgetNVerify( + draggableWidgets.MULTISELECT, + 450, + 200, + ); + + entityExplorer.NavigateToSwitcher("Explorer"); + + dataSources.CreateDataSource("Postgres"); + + cy.get("@dsName").then((dsName) => { + entityExplorer.NavigateToSwitcher("Widgets"); + + entityExplorer.SelectEntityByName("MultiSelect1", "Widgets"); + + oneClickBinding.ChooseAndAssertForm( + `${dsName}`, + dsName, + "public.employees", + { + label: "first_name", + value: "last_name", + }, + ); + }); + + agHelper.GetNClick(oneClickBindingLocator.connectData); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT, 450, 500); + + propPane.UpdatePropertyFieldValue( + "Text", + `{{MultiSelect1.selectedOptionLabels.toString()}}:{{MultiSelect1.selectedOptionValues.toString()}}`, + ); + + [ + { + label: "Andrew", + text: "Andrew:Fuller", + }, + { + label: "Janet", + text: "Andrew,Janet:Fuller,Leverling", + }, + { + label: "Margaret", + text: "Andrew,Janet,Margaret:Fuller,Leverling,Peacock", + }, + ].forEach((d) => { + cy.get(formWidgetsPage.multiSelectWidget) + .find(".rc-select-selector") + .click({ + force: true, + }); + + cy.get(".rc-select-item").contains(d.label).click({ + force: true, + }); + cy.get(commonlocators.TextInside).first().should("have.text", d.text); + }); + + agHelper.Sleep(2000); + + cy.get(formWidgetsPage.multiSelectWidget) + .find(".rc-select-selector") + .click({ + force: true, + }); + + cy.get(formWidgetsPage.multiselectwidgetv2) + .find(".rc-select-selection-search-input") + .first() + .focus({ force: true } as any) + .type("Anne", { force: true }); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + cy.get(".rc-select-item").contains("Anne").should("exist"); + }); +}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/PropertyControl_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/PropertyControl_spec.ts index d625185c02..0b48b11dd0 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/PropertyControl_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/PropertyControl_spec.ts @@ -99,23 +99,17 @@ describe("excludeForAirgap", "One click binding control", () => { propPane.ToggleJSMode("Table data", false); - oneClickBinding.ChooseAndAssertForm( - "Users", - "Users", - "public.users", - "gender", - ); + oneClickBinding.ChooseAndAssertForm("Users", "Users", "public.users", { + searchableColumn: "gender", + }); propPane.MoveToTab("Style"); propPane.MoveToTab("Content"); - oneClickBinding.ChooseAndAssertForm( - "sample Movies", - "movies", - "movies", - "status", - ); + oneClickBinding.ChooseAndAssertForm("sample Movies", "movies", "movies", { + searchableColumn: "status", + }); entityExplorer.NavigateToSwitcher("Explorer"); dataSources.NavigateToDSCreateNew(); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/mongoDB_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/mongoDB_spec.ts new file mode 100644 index 0000000000..966380d01d --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/mongoDB_spec.ts @@ -0,0 +1,98 @@ +import oneClickBindingLocator from "../../../../../locators/OneClickBindingLocator"; +import { OneClickBinding } from "../spec_utility"; +import { + agHelper, + entityExplorer, + dataSources, + draggableWidgets, + assertHelper, + propPane, +} from "../../../../../support/Objects/ObjectsCore"; +import formWidgetsPage from "../../../../../locators/FormWidgets.json"; +import widgetsPage from "../../../../../locators/Widgets.json"; +import commonlocators from "../../../../../locators/commonlocators.json"; + +const oneClickBinding = new OneClickBinding(); + +describe("Table widget one click binding feature", () => { + it("should check that queries are created and bound to table widget properly", () => { + entityExplorer.DragDropWidgetNVerify(draggableWidgets.SELECT, 450, 200); + + entityExplorer.NavigateToSwitcher("Explorer"); + + dataSources.CreateDataSource("Mongo"); + + cy.get("@dsName").then((dsName) => { + entityExplorer.NavigateToSwitcher("Widgets"); + + entityExplorer.SelectEntityByName("Select1", "Widgets"); + + oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "netflix", { + label: "name", + value: "director", + }); + }); + + agHelper.GetNClick(oneClickBindingLocator.connectData); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT, 450, 500); + + propPane.UpdatePropertyFieldValue( + "Text", + `{{Select1.selectedOptionLabel}}:{{Select1.selectedOptionValue}}`, + ); + + [ + { + label: "I Care a Lot", + text: "I Care a Lot:J Blakeson", + }, + { + label: "tick, tick...BOOM!", + text: "tick, tick...BOOM!:Lin-Manuel Miranda", + }, + { + label: "Munich – The Edge of War", + text: "Munich – The Edge of War:Christian Schwochow", + }, + ].forEach((d) => { + cy.get(formWidgetsPage.selectWidget) + .find(widgetsPage.dropdownSingleSelect) + .click({ + force: true, + }); + + cy.get(commonlocators.singleSelectWidgetMenuItem) + .contains(d.label) + .click({ + force: true, + }); + + cy.get(commonlocators.TextInside).first().should("have.text", d.text); + }); + + cy.get(formWidgetsPage.selectWidget) + .find(widgetsPage.dropdownSingleSelect) + .click({ + force: true, + }); + + cy.get(commonlocators.selectInputSearch).type("I Care a Lot"); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + cy.get(".select-popover-wrapper .menu-item-link") + .children() + .should("have.length", 1); + + agHelper.AssertElementExist( + commonlocators.singleSelectWidgetMenuItem + `:contains(I Care a Lot)`, + ); + }); +}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/postgres_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/postgres_spec.ts new file mode 100644 index 0000000000..5e3ed05e47 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/SelectWidget/postgres_spec.ts @@ -0,0 +1,103 @@ +import oneClickBindingLocator from "../../../../../locators/OneClickBindingLocator"; +import { OneClickBinding } from "../spec_utility"; +import { + agHelper, + entityExplorer, + dataSources, + draggableWidgets, + assertHelper, + propPane, +} from "../../../../../support/Objects/ObjectsCore"; +import formWidgetsPage from "../../../../../locators/FormWidgets.json"; +import widgetsPage from "../../../../../locators/Widgets.json"; +import commonlocators from "../../../../../locators/commonlocators.json"; + +const oneClickBinding = new OneClickBinding(); + +describe("Table widget one click binding feature", () => { + it("should check that queries are created and bound to table widget properly", () => { + entityExplorer.DragDropWidgetNVerify(draggableWidgets.SELECT, 450, 200); + + entityExplorer.NavigateToSwitcher("Explorer"); + + dataSources.CreateDataSource("Postgres"); + + cy.get("@dsName").then((dsName) => { + entityExplorer.NavigateToSwitcher("Widgets"); + + entityExplorer.SelectEntityByName("Select1", "Widgets"); + + oneClickBinding.ChooseAndAssertForm( + `${dsName}`, + dsName, + "public.employees", + { + label: "first_name", + value: "last_name", + }, + ); + }); + + agHelper.GetNClick(oneClickBindingLocator.connectData); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT, 450, 500); + + propPane.UpdatePropertyFieldValue( + "Text", + `{{Select1.selectedOptionLabel}}:{{Select1.selectedOptionValue}}`, + ); + + [ + { + label: "Andrew", + text: "Andrew:Fuller", + }, + { + label: "Janet", + text: "Janet:Leverling", + }, + { + label: "Margaret", + text: "Margaret:Peacock", + }, + ].forEach((d) => { + cy.get(formWidgetsPage.selectWidget) + .find(widgetsPage.dropdownSingleSelect) + .click({ + force: true, + }); + + cy.get(commonlocators.singleSelectWidgetMenuItem) + .contains(d.label) + .click({ + force: true, + }); + + cy.get(commonlocators.TextInside).first().should("have.text", d.text); + }); + + cy.get(formWidgetsPage.selectWidget) + .find(widgetsPage.dropdownSingleSelect) + .click({ + force: true, + }); + + cy.get(commonlocators.selectInputSearch).type("Anne"); + + assertHelper.AssertNetworkStatus("@postExecute"); + + agHelper.Sleep(2000); + + cy.get(".select-popover-wrapper .menu-item-link") + .children() + .should("have.length", 1); + + agHelper.AssertElementExist( + commonlocators.singleSelectWidgetMenuItem + `:contains(Anne)`, + ); + }); +}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mongoDB_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mongoDB_spec.ts index 80593f47ce..4dc20458c0 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mongoDB_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mongoDB_spec.ts @@ -25,12 +25,9 @@ describe("one click binding mongodb datasource", function () { cy.get("@dsName").then((dsName) => { entityExplorer.SelectEntityByName("Table1", "Widgets"); - oneClickBinding.ChooseAndAssertForm( - `${dsName}`, - dsName, - "netflix", - "creator", - ); + oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "netflix", { + searchableColumn: "creator", + }); }); agHelper.GetNClick(oneClickBindingLocator.connectData); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mysql_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mysql_spec.ts index 17588c862a..c9f15b0e3d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mysql_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/mysql_spec.ts @@ -23,12 +23,9 @@ describe.skip("Table widget one click binding feature", () => { entityExplorer.SelectEntityByName("Table1", "Widgets"); - oneClickBinding.ChooseAndAssertForm( - `${dsName}`, - dsName, - "configs", - "configName", - ); + oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "configs", { + searchableColumn: "configName", + }); }); agHelper.GetNClick(oneClickBindingLocator.connectData); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/postgres_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/postgres_spec.ts index ca7a95a439..fbb035a611 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/postgres_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/TableWidget/postgres_spec.ts @@ -28,7 +28,9 @@ describe("Table widget one click binding feature", () => { `${dsName}`, dsName, "public.employees", - "first_name", + { + searchableColumn: "first_name", + }, ); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/spec_utility.ts b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/spec_utility.ts index 72aa10f719..60d4106c7b 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/spec_utility.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/OneClickBinding/spec_utility.ts @@ -6,7 +6,7 @@ export class OneClickBinding { source?: string, selectedSource?: any, table?: string, - column?: string, + column: Record = {}, ) { agHelper.GetNClick(oneClickBindingLocator.datasourceDropdownSelector); @@ -37,17 +37,19 @@ export class OneClickBinding { oneClickBindingLocator.tableOrSpreadsheetSelectedOption(table), ); - agHelper.AssertElementExist(oneClickBindingLocator.searchableColumn); + Object.entries(column).forEach(([key, value]) => { + agHelper.AssertElementExist((oneClickBindingLocator as any)[key]); - agHelper.GetNClick(oneClickBindingLocator.searchableColumn); + agHelper.GetNClick((oneClickBindingLocator as any)[key]); - agHelper.GetNClick( - oneClickBindingLocator.searchableColumnDropdownOption(column), - ); + agHelper.GetNClick( + oneClickBindingLocator.columnDropdownOption(key, value), + ); - agHelper.AssertElementExist( - oneClickBindingLocator.searchableColumnSelectedOption(column), - ); + agHelper.AssertElementExist( + oneClickBindingLocator.columnSelectedOption(key, value), + ); + }); agHelper.AssertElementExist(oneClickBindingLocator.connectData); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_spec.js index 79b862989b..73ad0362a4 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_spec.js @@ -17,6 +17,7 @@ describe("Dropdown Widget Functionality", function () { it("should check that empty value is allowed in options", () => { cy.openPropertyPane("selectwidget"); + _.propPane.ToggleJSMode("sourcedata"); cy.updateCodeInput( ".t--property-control-sourcedata", `[ @@ -35,16 +36,16 @@ describe("Dropdown Widget Functionality", function () { ]`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("label key"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("value key"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "not.exist", ); }); @@ -68,7 +69,7 @@ describe("Dropdown Widget Functionality", function () { } ]`, ); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "exist", ); }); @@ -91,9 +92,7 @@ describe("Dropdown Widget Functionality", function () { }]`, ); cy.updateCodeInput(".t--property-control-defaultselectedvalue", "BLUE"); - cy.get(".t--property-control-value .t--codemirror-has-error").should( - "not.exist", - ); + cy.get(".t--property-key .t--codemirror-has-error").should("not.exist"); cy.get( ".t--property-control-defaultselectedvalue .t--codemirror-has-error", ).should("not.exist"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Select_Widgets_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Select_Widgets_spec.js index 2fd91391d9..4b9cca76e5 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Select_Widgets_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Select_Widgets_spec.js @@ -21,6 +21,8 @@ describe("Select Widgets", function () { 100, ); + _.propPane.ToggleJSMode("sourcedata"); + _.propPane.UpdatePropertyFieldValue( "Source Data", `{{[{ @@ -29,14 +31,14 @@ describe("Select Widgets", function () { }]}}`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("label key"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("value key"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); _.propPane.UpdatePropertyFieldValue( "Default selected values", @@ -50,6 +52,8 @@ describe("Select Widgets", function () { _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 250, 300); + _.propPane.ToggleJSMode("sourcedata"); + _.propPane.UpdatePropertyFieldValue( "Source Data", `{{[{ @@ -58,14 +62,14 @@ describe("Select Widgets", function () { }]}}`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("label key"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("value key"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); _.propPane.UpdatePropertyFieldValue( "Default selected value", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect1_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect1_spec.js index 70315aed59..d170eb25e0 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect1_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect1_spec.js @@ -12,6 +12,7 @@ describe("MultiSelect Widget Functionality", function () { _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT); //should check that empty value is allowed in options", () => { cy.openPropertyPane("multiselectwidgetv2"); + _.propPane.ToggleJSMode("sourcedata"); cy.updateCodeInput( ".t--property-control-sourcedata", `[ @@ -30,16 +31,16 @@ describe("MultiSelect Widget Functionality", function () { ]`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("labelkey"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("valuekey"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "not.exist", ); }); @@ -63,7 +64,7 @@ describe("MultiSelect Widget Functionality", function () { } ]`, ); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "exist", ); }); @@ -96,7 +97,7 @@ describe("MultiSelect Widget Functionality", function () { } ]`, ); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "not.exist", ); cy.get( @@ -135,7 +136,7 @@ describe("MultiSelect Widget Functionality", function () { "RED" ]`, ); - cy.get(".t--property-control-value .t--codemirror-has-error").should( + cy.get(".t--property-control-valuekey .t--codemirror-has-error").should( "not.exist", ); cy.get( diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect2_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect2_spec.js index b9e71d46ad..ef25af37c3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect2_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect2_spec.js @@ -18,19 +18,20 @@ describe("MultiSelect Widget Functionality", function () { it("1. Selects value with invalid default value", () => { cy.openPropertyPane("multiselectwidgetv2"); + _.propPane.ToggleJSMode("sourcedata"); _.propPane.UpdatePropertyFieldValue( "Source Data", JSON.stringify(data.input), ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("labelkey"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("valuekey"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); _.propPane.UpdatePropertyFieldValue( "Default selected values", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect4_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect4_spec.js index 1a04d0b58b..fccb173855 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect4_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect4_spec.js @@ -17,6 +17,7 @@ describe("MultiSelect Widget Functionality", function () { }); it("1. Add new multiselect widget", () => { _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT); + _.propPane.ToggleJSMode("sourcedata"); _.propPane.UpdatePropertyFieldValue( "Source Data", `[ @@ -35,14 +36,14 @@ describe("MultiSelect Widget Functionality", function () { ]`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("labelkey"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("valuekey"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); _.propPane.UpdatePropertyFieldValue( "Default selected values", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect_label_value.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect_label_value.ts index a0c0a0629e..c5d02d001d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect_label_value.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Multiselect/MultiSelect_label_value.ts @@ -20,6 +20,8 @@ describe("Select Widget Functionality", function () { ); _.agHelper.AssertElementExist(".t--widget-multiselectwidgetv2"); + _.propPane.ToggleJSMode("sourcedata"); + _.propPane.UpdatePropertyFieldValue( "Source Data", `[ @@ -39,12 +41,12 @@ describe("Select Widget Functionality", function () { ]`, ); - _.agHelper.GetNClick(_.propPane._selectPropDropdown("label")); + _.agHelper.GetNClick(_.propPane._selectPropDropdown("labelkey")); ["1", "2", "3"].forEach((d) => { _.agHelper.AssertElementExist(_.propPane._dropDownValue(d)); }); - _.agHelper.GetNClick(_.propPane._selectPropDropdown("value"), 0, true); + _.agHelper.GetNClick(_.propPane._selectPropDropdown("valuekey"), 0, true); ["1", "2", "3"].forEach((d) => { _.agHelper.AssertElementExist(_.propPane._dropDownValue(d)); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_label_value.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_label_value.ts index 236a9e2e2c..bdeb3cb1b4 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_label_value.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_label_value.ts @@ -16,6 +16,8 @@ describe("Select Widget Functionality", function () { _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 450, 200); _.agHelper.AssertElementExist(".t--widget-selectwidget"); + _.propPane.ToggleJSMode("sourcedata"); + _.propPane.UpdatePropertyFieldValue( "Source Data", `[ @@ -35,12 +37,12 @@ describe("Select Widget Functionality", function () { ]`, ); - _.agHelper.GetNClick(_.propPane._selectPropDropdown("label")); + _.agHelper.GetNClick(_.propPane._selectPropDropdown("labelkey")); ["1", "2", "3"].forEach((d) => { _.agHelper.AssertElementExist(_.propPane._dropDownValue(d)); }); - _.agHelper.GetNClick(_.propPane._selectPropDropdown("value"), 0, true); + _.agHelper.GetNClick(_.propPane._selectPropDropdown("valuekey"), 0, true); ["1", "2", "3"].forEach((d) => { _.agHelper.AssertElementExist(_.propPane._dropDownValue(d)); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_widget1_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_widget1_spec.js index 6e195d2a63..27f09fe84f 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_widget1_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/Select_widget1_spec.js @@ -20,6 +20,7 @@ describe("Select Widget Functionality", function () { cy.get(explorer.addWidget).click(); cy.dragAndDropToCanvas("selectwidget", { x: 300, y: 300 }); cy.get(".t--widget-selectwidget").should("exist"); + _.propPane.ToggleJSMode("sourcedata"); cy.updateCodeInput( ".t--property-control-sourcedata", `[ @@ -38,14 +39,14 @@ describe("Select Widget Functionality", function () { ]`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("labelkey"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("valuekey"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); cy.updateCodeInput( ".t--property-control-defaultselectedvalue", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/select_Widget_Bug_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/select_Widget_Bug_spec.js index dc10175ec5..eba6f6b1c8 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/select_Widget_Bug_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Select/select_Widget_Bug_spec.js @@ -20,6 +20,7 @@ describe("Select Widget Functionality", function () { it("should check that virtualization works well", () => { cy.openPropertyPane("selectwidget"); + _.propPane.ToggleJSMode("sourcedata"); cy.updateCodeInput( ".t--property-control-sourcedata", `[ @@ -50,14 +51,14 @@ describe("Select Widget Functionality", function () { ]`, ); - _.propPane.ToggleJSMode("label"); + _.propPane.ToggleJSMode("labelkey"); cy.updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - _.propPane.ToggleJSMode("value"); - cy.updateCodeInput(".t--property-control-value", `value`); + _.propPane.ToggleJSMode("valuekey"); + cy.updateCodeInput(".t--property-control-valuekey", `value`); cy.get(".t--property-control-value .t--codemirror-has-error").should( "not.exist", diff --git a/app/client/cypress/e2e/Regression/ServerSide/OnLoadTests/JsOnLoad3_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/OnLoadTests/JsOnLoad3_Spec.ts index e87f95bacd..2147053fb3 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/OnLoadTests/JsOnLoad3_Spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/OnLoadTests/JsOnLoad3_Spec.ts @@ -304,6 +304,7 @@ describe("JSObjects OnLoad Actions tests", function () { //jsEditor.EnableDisableAsyncFuncSettings("callCountry", false, true); Bug # 13826 entityExplorer.SelectEntityByName("Select1", "Widgets"); + propPane.ToggleJSMode("sourcedata"); propPane.UpdatePropertyFieldValue( "Source Data", `{{ getCitiesList.data.map((row) => { diff --git a/app/client/cypress/e2e/Regression/ServerSide/Params/PassingParams_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/Params/PassingParams_Spec.ts index 71ea28efac..5c2894dcb5 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/Params/PassingParams_Spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/Params/PassingParams_Spec.ts @@ -18,19 +18,20 @@ describe("Bug #10784 - Passing params from JS to SQL query should not break", () before(() => { entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 100, 100); entityExplorer.DragDropWidgetNVerify(draggableWidgets.SELECT, 500, 100); + propPane.ToggleJSMode("sourcedata"); propPane.UpdatePropertyFieldValue( "Source Data", `[\n {\n \"label\": \"7\",\n \"value\": \"7\"\n },\n {\n \"label\": \"8\",\n \"value\": \"8\"\n },\n {\n \"label\": \"9\",\n \"value\": \"9\"\n }\n]`, ); - propPane.ToggleJSMode("label"); + propPane.ToggleJSMode("labelkey"); (cy as any).updateCodeInput( - ".t--property-control-wrapper.t--property-control-label", + ".t--property-control-wrapper.t--property-control-labelkey", `label`, ); - propPane.ToggleJSMode("value"); - (cy as any).updateCodeInput(".t--property-control-value", `value`); + propPane.ToggleJSMode("valuekey"); + (cy as any).updateCodeInput(".t--property-control-valuekey", `value`); propPane.UpdatePropertyFieldValue( "Default selected value", diff --git a/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts b/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts index 2a4e230ba8..4ef7aa1ae5 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts +++ b/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts @@ -150,7 +150,9 @@ describe("Validate MsSQL connection & basic querying with UI flows", () => { it.skip("3.One click binding - should check that queries are created and bound to table widget properly", () => { entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 450, 200); - oneClickBinding.ChooseAndAssertForm(dsName, dsName, "Simpsons", "title"); + oneClickBinding.ChooseAndAssertForm(dsName, dsName, "Simpsons", { + searchableColumn: "title", + }); agHelper.GetNClick(oneClickBindingLocator.connectData); diff --git a/app/client/cypress/fixtures/MultipleWidgetDsl.json b/app/client/cypress/fixtures/MultipleWidgetDsl.json index 0de3f0ad34..00bfc1ce25 100644 --- a/app/client/cypress/fixtures/MultipleWidgetDsl.json +++ b/app/client/cypress/fixtures/MultipleWidgetDsl.json @@ -42,6 +42,7 @@ "sourceData": "", "optionLabel": "label", "optionValue": "value", + "dynamicPropertyPathList": [{"key": "sourceData"}], "widgetName": "Dropdown1", "defaultOptionValue": { "value":"VEG", diff --git a/app/client/cypress/fixtures/formSelectDsl.json b/app/client/cypress/fixtures/formSelectDsl.json index ed281f82cb..93321946d1 100644 --- a/app/client/cypress/fixtures/formSelectDsl.json +++ b/app/client/cypress/fixtures/formSelectDsl.json @@ -147,6 +147,7 @@ "bottomRow": 23, "parentId": "anq2not518", "dynamicBindingPathList": [], + "dynamicPropertyPathList": [{"key": "sourceData"}], "dynamicTriggerPathList": [] } ], diff --git a/app/client/cypress/fixtures/formSelectTreeselectDsl.json b/app/client/cypress/fixtures/formSelectTreeselectDsl.json index e4f2471f5b..aedf94a22e 100644 --- a/app/client/cypress/fixtures/formSelectTreeselectDsl.json +++ b/app/client/cypress/fixtures/formSelectTreeselectDsl.json @@ -140,6 +140,7 @@ "sourceData": "[\n {\n \"label\": \"Blue\",\n \"value\": 0\n },\n {\n \"label\": \"Green\",\n \"value\": \"GREEN\"\n },\n {\n \"label\": \"Red\",\n \"value\": \"RED\"\n },\n\t{\n \"label\": \"Red2\",\n \"value\": \"\"\n }\n]", "optionLabel": "label", "optionValue": "value", + "dynamicPropertyPathList": [{"key": "sourceData"}], "placeholderText": "Select option", "isDisabled": false, "key": "ber0u80gjl", diff --git a/app/client/cypress/fixtures/multiSelectDsl.json b/app/client/cypress/fixtures/multiSelectDsl.json index 6d68ebf02e..5ad55a4456 100644 --- a/app/client/cypress/fixtures/multiSelectDsl.json +++ b/app/client/cypress/fixtures/multiSelectDsl.json @@ -137,6 +137,7 @@ "sourceData": "", "optionLabel": "label", "optionValue": "value", + "dynamicPropertyPathList": [{"key": "sourceData"}], "isDisabled": false }, { diff --git a/app/client/cypress/fixtures/newFormDsl.json b/app/client/cypress/fixtures/newFormDsl.json index 9558adac3e..a12ae1171e 100644 --- a/app/client/cypress/fixtures/newFormDsl.json +++ b/app/client/cypress/fixtures/newFormDsl.json @@ -95,6 +95,7 @@ "sourceData": "", "optionLabel": "label", "optionValue": "value", + "dynamicPropertyPathList": [{"key": "sourceData"}], "widgetName": "Dropdown1", "type": "SELECT_WIDGET", "isLoading": false, @@ -135,6 +136,7 @@ "leftColumn": 10, "optionLable": "label", "optionValue": "value", + "dynamicPropertyPathList": [{"key": "sourceData"}], "sourceData": [ { "label": "Hashirama Senju", diff --git a/app/client/cypress/locators/FormWidgets.json b/app/client/cypress/locators/FormWidgets.json index 165cbc997a..95d3c05145 100644 --- a/app/client/cypress/locators/FormWidgets.json +++ b/app/client/cypress/locators/FormWidgets.json @@ -4,6 +4,7 @@ "dropdownWidget": ".t--draggable-selectwidget", "menuButtonWidget": ".t--draggable-menubuttonwidget", "multiselectwidgetv2": ".t--draggable-multiselectwidgetv2", + "multiselectWidgetv2search": ".multi-select-dropdown .bp3-input", "multiselecttreeWidget": ".t--draggable-multiselecttreewidget", "singleselecttreeWidget": ".t--draggable-singleselecttreewidget", "dropdownSelectionType": ".t--property-control-selectiontype .bp3-popover-target", diff --git a/app/client/cypress/locators/OneClickBindingLocator.ts b/app/client/cypress/locators/OneClickBindingLocator.ts index 847c22aa21..781a8e4bb9 100644 --- a/app/client/cypress/locators/OneClickBindingLocator.ts +++ b/app/client/cypress/locators/OneClickBindingLocator.ts @@ -34,16 +34,6 @@ export default { `[data-testid="t--one-click-binding-table-selector"] .rc-select-selection-item${ table ? `:contains(${table})` : "" }`, - searchableColumn: - '[data-testId="t--one-click-binding-column-searchableColumn"]', - searchableColumnDropdownOption: (column?: string) => - `[data-testId='t--one-click-binding-column-searchableColumn--column']${ - column ? `:contains(${column})` : "" - }`, - searchableColumnSelectedOption: (column?: string) => - `[data-testId="t--one-click-binding-column-searchableColumn"] .rc-select-selection-item${ - column ? `:contains(${column})` : "" - }`, validTableRowData: '.t--widget-tablewidgetv2 [role="rowgroup"] [role="button"]', tableError: (error: string) => @@ -52,4 +42,16 @@ export default { dayViewFromDate: ".DayPicker-Day", loadMore: "[data-testId='t--one-click-binding-datasource--load-more']", datasourceSearch: `[data-testId="t--one-click-binding-datasource--search"]`, + searchableColumn: + '[data-testId="t--one-click-binding-column-searchableColumn"]', + label: '[data-testId="t--one-click-binding-column-label"]', + value: '[data-testId="t--one-click-binding-column-value"]', + columnDropdownOption: (column: string, value?: string) => + `[data-testId='t--one-click-binding-column-${column}--column']${ + value ? `:contains(${value})` : "" + }`, + columnSelectedOption: (column: string, value?: string) => + `[data-testId="t--one-click-binding-column-${column}"] .rc-select-selection-item${ + value ? `:contains(${value})` : "" + }`, }; diff --git a/app/client/src/WidgetQueryGenerators/GSheets/index.ts b/app/client/src/WidgetQueryGenerators/GSheets/index.ts index ac0dcdfa75..b55765c26f 100644 --- a/app/client/src/WidgetQueryGenerators/GSheets/index.ts +++ b/app/client/src/WidgetQueryGenerators/GSheets/index.ts @@ -54,35 +54,10 @@ export default abstract class GSheets extends BaseQueryGenerator { const { select } = widgetConfig; if (select && formConfig.sheetName) { - return { + const queryPayload: any = { type: QUERY_TYPE.SELECT, name: `Find_${removeSpecialChars(formConfig.sheetName)}`, formData: { - where: { - data: { - children: [ - { - condition: "CONTAINS", - key: `{{${select["where"]} ? "${formConfig.searchableColumn}" : ""}}`, - value: `{{${select["where"]}}}`, - }, - ], - }, - }, - sortBy: { - data: [ - { - column: `{{${select["orderBy"]}}}`, - order: select["sortOrder"], - }, - ], - }, - pagination: { - data: { - limit: `{{${select["limit"]}}}`, - offset: `{{${select["offset"]}}}`, - }, - }, ...this.buildBasicConfig( COMMAND_TYPES.FIND, formConfig.tableName, @@ -90,18 +65,56 @@ export default abstract class GSheets extends BaseQueryGenerator { formConfig.tableHeaderIndex, ), }, - dynamicBindingPathList: [ - { - key: "formData.where.data", - }, - { - key: "formData.sortBy.data", - }, - { - key: "formData.pagination.data", - }, - ], + dynamicBindingPathList: [], }; + + if (select["where"]) { + queryPayload.formData.where = { + data: { + children: [ + { + condition: "CONTAINS", + key: `{{${select["where"]} ? "${formConfig.searchableColumn}" : ""}}`, + value: `{{${select["where"]}}}`, + }, + ], + }, + }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.where.data", + }); + } + + if (select["sortOrder"] && select["orderBy"]) { + queryPayload.formData.sortBy = { + data: [ + { + column: `{{${select["orderBy"]}}}`, + order: select["sortOrder"], + }, + ], + }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.sortBy.data", + }); + } + + if (select["limit"] && select["offset"]) { + queryPayload.formData.pagination = { + data: { + limit: `{{${select["limit"]}}}`, + offset: `{{${select["offset"]}}}`, + }, + }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.pagination.data", + }); + } + + return queryPayload; } } diff --git a/app/client/src/WidgetQueryGenerators/MongoDB/index.test.ts b/app/client/src/WidgetQueryGenerators/MongoDB/index.test.ts index 5aad103cee..a51973bc02 100644 --- a/app/client/src/WidgetQueryGenerators/MongoDB/index.test.ts +++ b/app/client/src/WidgetQueryGenerators/MongoDB/index.test.ts @@ -77,7 +77,7 @@ describe("Mongo WidgetQueryGenerator", () => { data: "{{data_table.pageSize}}", }, query: { - data: '{{{ title: {$regex: data_table.searchText||""} }}}', + data: `{{{ title: {$regex: data_table.searchText||"", '$options' : 'i'} }}}`, }, skip: { data: "{{(data_table.pageNo - 1) * data_table.pageSize}}", @@ -152,7 +152,7 @@ describe("Mongo WidgetQueryGenerator", () => { data: "{{data_table.pageSize}}", }, query: { - data: '{{{ title: {$regex: data_table.searchText||""} }}}', + data: `{{{ title: {$regex: data_table.searchText||"", '$options' : 'i'} }}}`, }, skip: { data: "{{(data_table.pageNo - 1) * data_table.pageSize}}", diff --git a/app/client/src/WidgetQueryGenerators/MongoDB/index.ts b/app/client/src/WidgetQueryGenerators/MongoDB/index.ts index 6039bdb7d7..cf6b3c1b45 100644 --- a/app/client/src/WidgetQueryGenerators/MongoDB/index.ts +++ b/app/client/src/WidgetQueryGenerators/MongoDB/index.ts @@ -30,39 +30,66 @@ export default abstract class MongoDB extends BaseQueryGenerator { const { select } = widgetConfig; if (select) { - return { + const queryPayload: any = { type: QUERY_TYPE.SELECT, name: `Find_${removeSpecialChars(formConfig.tableName)}`, formData: { find: { - skip: { data: `{{${select["offset"]}}}` }, + skip: { data: "" }, query: { - data: formConfig.searchableColumn - ? `{{{ ${formConfig.searchableColumn}: {$regex: ${select["where"]}} }}}` - : "", + data: "", }, sort: { - data: `{{ ${select["orderBy"]} ? { [${select["orderBy"]}]: ${select["sortOrder"]} ? 1 : -1 } : {}}}`, + data: "", + }, + limit: { + data: "", }, - limit: { data: `{{${select["limit"]}}}` }, }, ...this.buildBasicConfig(COMMAND_TYPES.FIND, formConfig.tableName), }, - dynamicBindingPathList: [ - { - key: "formData.find.skip.data", - }, - { - key: "formData.find.query.data", - }, - { - key: "formData.find.sort.data", - }, - { - key: "formData.find.limit.data", - }, - ], + dynamicBindingPathList: [], }; + + if (select["offset"]) { + queryPayload.formData.find.skip = { data: `{{${select["offset"]}}}` }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.find.skip.data", + }); + } + + if (formConfig.searchableColumn) { + queryPayload.formData.find.query = { + data: formConfig.searchableColumn + ? `{{{ ${formConfig.searchableColumn}: {$regex: ${select["where"]}, '$options' : 'i'} }}}` + : "", + }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.find.query.data", + }); + } + + if (select["orderBy"] && select["sortOrder"]) { + queryPayload.formData.find.sort = { + data: `{{ ${select["orderBy"]} ? { [${select["orderBy"]}]: ${select["sortOrder"]} ? 1 : -1 } : {}}}`, + }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.find.sort.data", + }); + } + + if (select["limit"]) { + queryPayload.formData.find.limit = { data: `{{${select["limit"]}}}` }; + + queryPayload.dynamicBindingPathList.push({ + key: "formData.find.limit.data", + }); + } + + return queryPayload; } } diff --git a/app/client/src/WidgetQueryGenerators/types.ts b/app/client/src/WidgetQueryGenerators/types.ts index e8a6dd12d8..aeeae2d8e7 100644 --- a/app/client/src/WidgetQueryGenerators/types.ts +++ b/app/client/src/WidgetQueryGenerators/types.ts @@ -18,11 +18,11 @@ export type WidgetQueryGenerationFormConfig = { export type WidgetQueryGenerationConfig = { select?: { - limit: string; - offset: string; - where: string; - orderBy: string; - sortOrder: string; + limit?: string; + offset?: string; + where?: string; + orderBy?: string; + sortOrder?: string; }; create?: { value: string; @@ -31,7 +31,7 @@ export type WidgetQueryGenerationConfig = { value: string; where?: string; }; - totalRecord: boolean; + totalRecord?: boolean; }; export enum QUERY_TYPE { diff --git a/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx b/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx index 1c7ba41894..039a0d0b51 100644 --- a/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx +++ b/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx @@ -284,6 +284,7 @@ function getWidgetProps( { key: "sourceData" }, { key: "defaultOptionValue" }, ], + dynamicPropertyPathList: [{ key: "sourceData" }], }, }; case "TEXT_WIDGET": diff --git a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useDatasource.tsx b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useDatasource.tsx index 6936bedfc3..2a7707b6cb 100644 --- a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useDatasource.tsx +++ b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useDatasource.tsx @@ -106,6 +106,7 @@ export function useDatasource(searchText: string) { onSourceClose, propertyName, propertyValue, + sampleData, updateConfig, widgetId, } = useContext(WidgetQueryGeneratorFormContext); @@ -321,7 +322,7 @@ export function useDatasource(searchText: string) { const { pageId: currentPageId } = useParams(); const otherOptions = useMemo(() => { - return [ + const options = [ { icon: , id: "Connect new datasource", @@ -350,7 +351,35 @@ export function useDatasource(searchText: string) { }, }, ]; - }, [currentPageId, history, propertyName]); + + if (sampleData) { + options.push({ + icon: , + id: "Sample data", + label: "Sample data", + value: "Sample data", + onSelect: () => { + addBinding(sampleData, false); + + updateConfig({ + datasource: "", + datasourcePluginType: "", + datasourcePluginName: "", + datasourceConnectionMode: "", + }); + + AnalyticsUtil.logEvent("BIND_OTHER_ACTIONS", { + widgetName: widget.widgetName, + widgetType: widget.type, + propertyName: propertyName, + selectedAction: "Sample data", + }); + }, + }); + } + + return options; + }, [currentPageId, history, propertyName, sampleData, addBinding]); const queries = useSelector(getActionsForCurrentPage); @@ -439,31 +468,47 @@ export function useDatasource(searchText: string) { ]; }, [searchText, datasourceOptions, otherOptions, queryOptions]); + const selected = useMemo(() => { + let source; + + if (config.datasource) { + source = datasourceOptions.find( + (option) => option.id === config.datasource, + ); + } else if ( + sampleData === + (typeof propertyValue === "string" + ? propertyValue + : JSON.stringify(propertyValue, null, 2)) + ) { + source = otherOptions.find((option) => option.value === "Sample data"); + } else if (propertyValue) { + source = queryOptions.find((option) => option.value === propertyValue); + } + + if (source) { + return ( + + ); + } else { + return Connect data; + } + }, [ + config, + datasourceOptions, + sampleData, + propertyValue, + otherOptions, + queryOptions, + ]); + return { datasourceOptions: filteredDatasourceOptions, otherOptions, - selected: (() => { - let source; - - if (config.datasource) { - source = datasourceOptions.find( - (option) => option.id === config.datasource, - ); - } else if (propertyValue) { - source = queryOptions.find((option) => option.value === propertyValue); - } - - if (source) { - return ( - - ); - } else { - return Connect data; - } - })(), + selected, queryOptions: filteredQueryOptions, isSourceOpen, onSourceClose, diff --git a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/ConnectData/useConnectData.ts b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/ConnectData/useConnectData.ts index 6b987857af..ff10dfe5a2 100644 --- a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/ConnectData/useConnectData.ts +++ b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/ConnectData/useConnectData.ts @@ -1,7 +1,7 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import type { AppState } from "@appsmith/reducers"; import { PluginPackageName } from "entities/Action"; -import { useContext } from "react"; +import { useContext, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { getWidget } from "sagas/selectors"; import { getPluginPackageFromDatasourceId } from "selectors/entitiesSelector"; @@ -14,7 +14,7 @@ import { useColumns } from "../WidgetSpecificControls/ColumnDropdown/useColumns" export function useConnectData() { const dispatch = useDispatch(); - const { config, propertyName, widgetId } = useContext( + const { aliases, config, propertyName, widgetId } = useContext( WidgetQueryGeneratorFormContext, ); @@ -27,16 +27,30 @@ export function useConnectData() { ); const onClick = () => { + const searchableColumn = (() => { + if (config.searchableColumn) { + return config.searchableColumn; + } else { + const alias = aliases?.find((d) => d.isSearcheable)?.name; + + return alias && config.alias[alias]; + } + })(); + const payload = { tableName: config.table, sheetName: config.sheet, datasourceId: config.datasource, widgetId: widgetId, tableHeaderIndex: config.tableHeaderIndex, - searchableColumn: config.searchableColumn, + searchableColumn, columns: columns.map((column) => column.name), primaryColumn, connectionMode: config.datasourceConnectionMode, + aliases: Object.entries(config.alias).map(([key, value]) => ({ + name: key, + alias: value, + })), }; dispatch({ @@ -54,6 +68,7 @@ export function useConnectData() { additionalData: { dataTableName: config.table, searchableColumn: config.searchableColumn, + alias: config.alias, }, }); }; @@ -64,10 +79,17 @@ export function useConnectData() { const show = !!config.datasource; - const disabled = - !config.table || - (selectedDatasourcePluginPackageName === PluginPackageName.GOOGLE_SHEETS && - !isValidGsheetConfig(config)); + const disabled = useMemo(() => { + return ( + !config.table || + (selectedDatasourcePluginPackageName === + PluginPackageName.GOOGLE_SHEETS && + !isValidGsheetConfig(config)) || + aliases?.some((alias) => { + return alias.isRequired && !config.alias[alias.name]; + }) + ); + }, [config, aliases]); return { show, diff --git a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/WidgetSpecificControls/ColumnDropdown/index.tsx b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/WidgetSpecificControls/ColumnDropdown/index.tsx index 77a451061b..cc2fe0c910 100644 --- a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/WidgetSpecificControls/ColumnDropdown/index.tsx +++ b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/WidgetSpecificControls/ColumnDropdown/index.tsx @@ -6,6 +6,7 @@ import { ErrorMessage, Label, SelectWrapper } from "../../styles"; import { useColumns } from "./useColumns"; type Props = { + id: string; alias: string; label: string; onSelect: () => void; @@ -29,7 +30,7 @@ function ColumnDropdown(props: Props) {