feat: Integrate one click binding to sourceData of select and multi select widget (#25750)
## Description We have changed the property control of sourceData of select and multi select widget to dropdowns which has one click-binding items. #### PR fixes following issue(s) Fixes https://github.com/appsmithorg/appsmith/issues/24780 #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [ ] Cypress > > #### Test Plan >(https://github.com/appsmithorg/TestSmith/issues/2472) > > #### Issues raised during DP testing > (https://github.com/appsmithorg/appsmith/pull/25750#issuecomment-1665077044) > > > ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [x] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [x] Test plan has been peer reviewed by project stakeholders and other QA members - [x] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
This commit is contained in:
parent
0d533dab90
commit
727d30ad92
|
|
@ -2,6 +2,7 @@ const testdata = require("../../../../fixtures/testdata.json");
|
||||||
import {
|
import {
|
||||||
entityExplorer,
|
entityExplorer,
|
||||||
agHelper,
|
agHelper,
|
||||||
|
propPane,
|
||||||
} from "../../../../support/Objects/ObjectsCore";
|
} from "../../../../support/Objects/ObjectsCore";
|
||||||
|
|
||||||
describe("Binding the multiple widgets and validating default data", function () {
|
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 () {
|
it("1. Dropdown widget test with invalid binding value", function () {
|
||||||
entityExplorer.SelectEntityByName("Dropdown1");
|
entityExplorer.SelectEntityByName("Dropdown1");
|
||||||
|
propPane.ToggleJSMode("sourcedata");
|
||||||
cy.testJsontext("sourcedata", JSON.stringify(testdata.defaultdataBinding));
|
cy.testJsontext("sourcedata", JSON.stringify(testdata.defaultdataBinding));
|
||||||
cy.evaluateErrorMessage(testdata.dropdownErrorMsg);
|
cy.evaluateErrorMessage(testdata.dropdownErrorMsg);
|
||||||
//Table widget test with invalid binding value
|
//Table widget test with invalid binding value
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ describe("Binding the multiple widgets and validating default data", function ()
|
||||||
);
|
);
|
||||||
//Dropdown widget test with default value from table widget
|
//Dropdown widget test with default value from table widget
|
||||||
entityExplorer.SelectEntityByName("Dropdown1");
|
entityExplorer.SelectEntityByName("Dropdown1");
|
||||||
|
propPane.ToggleJSMode("sourcedata");
|
||||||
cy.testJsontext(
|
cy.testJsontext(
|
||||||
"sourcedata",
|
"sourcedata",
|
||||||
JSON.stringify(testdata.deafultDropDownWidget),
|
JSON.stringify(testdata.deafultDropDownWidget),
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,10 @@ describe("excludeForAirgap", "Widget property navigation", () => {
|
||||||
);
|
);
|
||||||
_.agHelper.GetNClick(OneClickBindingLocator.searchableColumn);
|
_.agHelper.GetNClick(OneClickBindingLocator.searchableColumn);
|
||||||
_.agHelper.GetNClick(
|
_.agHelper.GetNClick(
|
||||||
OneClickBindingLocator.searchableColumnDropdownOption(),
|
OneClickBindingLocator.columnDropdownOption(
|
||||||
|
"searchableColumn",
|
||||||
|
"imdb_id",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
_.agHelper.GetNClick(OneClickBindingLocator.connectData);
|
_.agHelper.GetNClick(OneClickBindingLocator.connectData);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -99,23 +99,17 @@ describe("excludeForAirgap", "One click binding control", () => {
|
||||||
|
|
||||||
propPane.ToggleJSMode("Table data", false);
|
propPane.ToggleJSMode("Table data", false);
|
||||||
|
|
||||||
oneClickBinding.ChooseAndAssertForm(
|
oneClickBinding.ChooseAndAssertForm("Users", "Users", "public.users", {
|
||||||
"Users",
|
searchableColumn: "gender",
|
||||||
"Users",
|
});
|
||||||
"public.users",
|
|
||||||
"gender",
|
|
||||||
);
|
|
||||||
|
|
||||||
propPane.MoveToTab("Style");
|
propPane.MoveToTab("Style");
|
||||||
|
|
||||||
propPane.MoveToTab("Content");
|
propPane.MoveToTab("Content");
|
||||||
|
|
||||||
oneClickBinding.ChooseAndAssertForm(
|
oneClickBinding.ChooseAndAssertForm("sample Movies", "movies", "movies", {
|
||||||
"sample Movies",
|
searchableColumn: "status",
|
||||||
"movies",
|
});
|
||||||
"movies",
|
|
||||||
"status",
|
|
||||||
);
|
|
||||||
|
|
||||||
entityExplorer.NavigateToSwitcher("Explorer");
|
entityExplorer.NavigateToSwitcher("Explorer");
|
||||||
dataSources.NavigateToDSCreateNew();
|
dataSources.NavigateToDSCreateNew();
|
||||||
|
|
|
||||||
|
|
@ -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)`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -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)`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -25,12 +25,9 @@ describe("one click binding mongodb datasource", function () {
|
||||||
cy.get("@dsName").then((dsName) => {
|
cy.get("@dsName").then((dsName) => {
|
||||||
entityExplorer.SelectEntityByName("Table1", "Widgets");
|
entityExplorer.SelectEntityByName("Table1", "Widgets");
|
||||||
|
|
||||||
oneClickBinding.ChooseAndAssertForm(
|
oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "netflix", {
|
||||||
`${dsName}`,
|
searchableColumn: "creator",
|
||||||
dsName,
|
});
|
||||||
"netflix",
|
|
||||||
"creator",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,9 @@ describe.skip("Table widget one click binding feature", () => {
|
||||||
|
|
||||||
entityExplorer.SelectEntityByName("Table1", "Widgets");
|
entityExplorer.SelectEntityByName("Table1", "Widgets");
|
||||||
|
|
||||||
oneClickBinding.ChooseAndAssertForm(
|
oneClickBinding.ChooseAndAssertForm(`${dsName}`, dsName, "configs", {
|
||||||
`${dsName}`,
|
searchableColumn: "configName",
|
||||||
dsName,
|
});
|
||||||
"configs",
|
|
||||||
"configName",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,9 @@ describe("Table widget one click binding feature", () => {
|
||||||
`${dsName}`,
|
`${dsName}`,
|
||||||
dsName,
|
dsName,
|
||||||
"public.employees",
|
"public.employees",
|
||||||
"first_name",
|
{
|
||||||
|
searchableColumn: "first_name",
|
||||||
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ export class OneClickBinding {
|
||||||
source?: string,
|
source?: string,
|
||||||
selectedSource?: any,
|
selectedSource?: any,
|
||||||
table?: string,
|
table?: string,
|
||||||
column?: string,
|
column: Record<string, string> = {},
|
||||||
) {
|
) {
|
||||||
agHelper.GetNClick(oneClickBindingLocator.datasourceDropdownSelector);
|
agHelper.GetNClick(oneClickBindingLocator.datasourceDropdownSelector);
|
||||||
|
|
||||||
|
|
@ -37,17 +37,19 @@ export class OneClickBinding {
|
||||||
oneClickBindingLocator.tableOrSpreadsheetSelectedOption(table),
|
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(
|
agHelper.GetNClick(
|
||||||
oneClickBindingLocator.searchableColumnDropdownOption(column),
|
oneClickBindingLocator.columnDropdownOption(key, value),
|
||||||
);
|
);
|
||||||
|
|
||||||
agHelper.AssertElementExist(
|
agHelper.AssertElementExist(
|
||||||
oneClickBindingLocator.searchableColumnSelectedOption(column),
|
oneClickBindingLocator.columnSelectedOption(key, value),
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
agHelper.AssertElementExist(oneClickBindingLocator.connectData);
|
agHelper.AssertElementExist(oneClickBindingLocator.connectData);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ describe("Dropdown Widget Functionality", function () {
|
||||||
|
|
||||||
it("should check that empty value is allowed in options", () => {
|
it("should check that empty value is allowed in options", () => {
|
||||||
cy.openPropertyPane("selectwidget");
|
cy.openPropertyPane("selectwidget");
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-sourcedata",
|
".t--property-control-sourcedata",
|
||||||
`[
|
`[
|
||||||
|
|
@ -35,16 +36,16 @@ describe("Dropdown Widget Functionality", function () {
|
||||||
]`,
|
]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("label key");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("value key");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
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",
|
"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",
|
"exist",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -91,9 +92,7 @@ describe("Dropdown Widget Functionality", function () {
|
||||||
}]`,
|
}]`,
|
||||||
);
|
);
|
||||||
cy.updateCodeInput(".t--property-control-defaultselectedvalue", "BLUE");
|
cy.updateCodeInput(".t--property-control-defaultselectedvalue", "BLUE");
|
||||||
cy.get(".t--property-control-value .t--codemirror-has-error").should(
|
cy.get(".t--property-key .t--codemirror-has-error").should("not.exist");
|
||||||
"not.exist",
|
|
||||||
);
|
|
||||||
cy.get(
|
cy.get(
|
||||||
".t--property-control-defaultselectedvalue .t--codemirror-has-error",
|
".t--property-control-defaultselectedvalue .t--codemirror-has-error",
|
||||||
).should("not.exist");
|
).should("not.exist");
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ describe("Select Widgets", function () {
|
||||||
100,
|
100,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"Source Data",
|
||||||
`{{[{
|
`{{[{
|
||||||
|
|
@ -29,14 +31,14 @@ describe("Select Widgets", function () {
|
||||||
}]}}`,
|
}]}}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("label key");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("value key");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Default selected values",
|
"Default selected values",
|
||||||
|
|
@ -50,6 +52,8 @@ describe("Select Widgets", function () {
|
||||||
|
|
||||||
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 250, 300);
|
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 250, 300);
|
||||||
|
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"Source Data",
|
||||||
`{{[{
|
`{{[{
|
||||||
|
|
@ -58,14 +62,14 @@ describe("Select Widgets", function () {
|
||||||
}]}}`,
|
}]}}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("label key");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("value key");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Default selected value",
|
"Default selected value",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT);
|
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT);
|
||||||
//should check that empty value is allowed in options", () => {
|
//should check that empty value is allowed in options", () => {
|
||||||
cy.openPropertyPane("multiselectwidgetv2");
|
cy.openPropertyPane("multiselectwidgetv2");
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-sourcedata",
|
".t--property-control-sourcedata",
|
||||||
`[
|
`[
|
||||||
|
|
@ -30,16 +31,16 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
]`,
|
]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("labelkey");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("valuekey");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
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",
|
"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",
|
"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",
|
"not.exist",
|
||||||
);
|
);
|
||||||
cy.get(
|
cy.get(
|
||||||
|
|
@ -135,7 +136,7 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
"RED"
|
"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",
|
"not.exist",
|
||||||
);
|
);
|
||||||
cy.get(
|
cy.get(
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,20 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
|
|
||||||
it("1. Selects value with invalid default value", () => {
|
it("1. Selects value with invalid default value", () => {
|
||||||
cy.openPropertyPane("multiselectwidgetv2");
|
cy.openPropertyPane("multiselectwidgetv2");
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"Source Data",
|
||||||
JSON.stringify(data.input),
|
JSON.stringify(data.input),
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("labelkey");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("valuekey");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Default selected values",
|
"Default selected values",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
});
|
});
|
||||||
it("1. Add new multiselect widget", () => {
|
it("1. Add new multiselect widget", () => {
|
||||||
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT);
|
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.MULTISELECT);
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"Source Data",
|
||||||
`[
|
`[
|
||||||
|
|
@ -35,14 +36,14 @@ describe("MultiSelect Widget Functionality", function () {
|
||||||
]`,
|
]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("labelkey");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("valuekey");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Default selected values",
|
"Default selected values",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ describe("Select Widget Functionality", function () {
|
||||||
);
|
);
|
||||||
_.agHelper.AssertElementExist(".t--widget-multiselectwidgetv2");
|
_.agHelper.AssertElementExist(".t--widget-multiselectwidgetv2");
|
||||||
|
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"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) => {
|
["1", "2", "3"].forEach((d) => {
|
||||||
_.agHelper.AssertElementExist(_.propPane._dropDownValue(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) => {
|
["1", "2", "3"].forEach((d) => {
|
||||||
_.agHelper.AssertElementExist(_.propPane._dropDownValue(d));
|
_.agHelper.AssertElementExist(_.propPane._dropDownValue(d));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ describe("Select Widget Functionality", function () {
|
||||||
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 450, 200);
|
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.SELECT, 450, 200);
|
||||||
_.agHelper.AssertElementExist(".t--widget-selectwidget");
|
_.agHelper.AssertElementExist(".t--widget-selectwidget");
|
||||||
|
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
|
|
||||||
_.propPane.UpdatePropertyFieldValue(
|
_.propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"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) => {
|
["1", "2", "3"].forEach((d) => {
|
||||||
_.agHelper.AssertElementExist(_.propPane._dropDownValue(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) => {
|
["1", "2", "3"].forEach((d) => {
|
||||||
_.agHelper.AssertElementExist(_.propPane._dropDownValue(d));
|
_.agHelper.AssertElementExist(_.propPane._dropDownValue(d));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ describe("Select Widget Functionality", function () {
|
||||||
cy.get(explorer.addWidget).click();
|
cy.get(explorer.addWidget).click();
|
||||||
cy.dragAndDropToCanvas("selectwidget", { x: 300, y: 300 });
|
cy.dragAndDropToCanvas("selectwidget", { x: 300, y: 300 });
|
||||||
cy.get(".t--widget-selectwidget").should("exist");
|
cy.get(".t--widget-selectwidget").should("exist");
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-sourcedata",
|
".t--property-control-sourcedata",
|
||||||
`[
|
`[
|
||||||
|
|
@ -38,14 +39,14 @@ describe("Select Widget Functionality", function () {
|
||||||
]`,
|
]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("labelkey");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("valuekey");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-defaultselectedvalue",
|
".t--property-control-defaultselectedvalue",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ describe("Select Widget Functionality", function () {
|
||||||
|
|
||||||
it("should check that virtualization works well", () => {
|
it("should check that virtualization works well", () => {
|
||||||
cy.openPropertyPane("selectwidget");
|
cy.openPropertyPane("selectwidget");
|
||||||
|
_.propPane.ToggleJSMode("sourcedata");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-sourcedata",
|
".t--property-control-sourcedata",
|
||||||
`[
|
`[
|
||||||
|
|
@ -50,14 +51,14 @@ describe("Select Widget Functionality", function () {
|
||||||
]`,
|
]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("label");
|
_.propPane.ToggleJSMode("labelkey");
|
||||||
cy.updateCodeInput(
|
cy.updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
_.propPane.ToggleJSMode("value");
|
_.propPane.ToggleJSMode("valuekey");
|
||||||
cy.updateCodeInput(".t--property-control-value", `value`);
|
cy.updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
cy.get(".t--property-control-value .t--codemirror-has-error").should(
|
cy.get(".t--property-control-value .t--codemirror-has-error").should(
|
||||||
"not.exist",
|
"not.exist",
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ describe("JSObjects OnLoad Actions tests", function () {
|
||||||
//jsEditor.EnableDisableAsyncFuncSettings("callCountry", false, true); Bug # 13826
|
//jsEditor.EnableDisableAsyncFuncSettings("callCountry", false, true); Bug # 13826
|
||||||
|
|
||||||
entityExplorer.SelectEntityByName("Select1", "Widgets");
|
entityExplorer.SelectEntityByName("Select1", "Widgets");
|
||||||
|
propPane.ToggleJSMode("sourcedata");
|
||||||
propPane.UpdatePropertyFieldValue(
|
propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"Source Data",
|
||||||
`{{ getCitiesList.data.map((row) => {
|
`{{ getCitiesList.data.map((row) => {
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,20 @@ describe("Bug #10784 - Passing params from JS to SQL query should not break", ()
|
||||||
before(() => {
|
before(() => {
|
||||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 100, 100);
|
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 100, 100);
|
||||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.SELECT, 500, 100);
|
entityExplorer.DragDropWidgetNVerify(draggableWidgets.SELECT, 500, 100);
|
||||||
|
propPane.ToggleJSMode("sourcedata");
|
||||||
propPane.UpdatePropertyFieldValue(
|
propPane.UpdatePropertyFieldValue(
|
||||||
"Source Data",
|
"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]`,
|
`[\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(
|
(cy as any).updateCodeInput(
|
||||||
".t--property-control-wrapper.t--property-control-label",
|
".t--property-control-wrapper.t--property-control-labelkey",
|
||||||
`label`,
|
`label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
propPane.ToggleJSMode("value");
|
propPane.ToggleJSMode("valuekey");
|
||||||
(cy as any).updateCodeInput(".t--property-control-value", `value`);
|
(cy as any).updateCodeInput(".t--property-control-valuekey", `value`);
|
||||||
|
|
||||||
propPane.UpdatePropertyFieldValue(
|
propPane.UpdatePropertyFieldValue(
|
||||||
"Default selected value",
|
"Default selected value",
|
||||||
|
|
|
||||||
|
|
@ -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", () => {
|
it.skip("3.One click binding - should check that queries are created and bound to table widget properly", () => {
|
||||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 450, 200);
|
entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 450, 200);
|
||||||
|
|
||||||
oneClickBinding.ChooseAndAssertForm(dsName, dsName, "Simpsons", "title");
|
oneClickBinding.ChooseAndAssertForm(dsName, dsName, "Simpsons", {
|
||||||
|
searchableColumn: "title",
|
||||||
|
});
|
||||||
|
|
||||||
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
agHelper.GetNClick(oneClickBindingLocator.connectData);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
"sourceData": "",
|
"sourceData": "",
|
||||||
"optionLabel": "label",
|
"optionLabel": "label",
|
||||||
"optionValue": "value",
|
"optionValue": "value",
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"widgetName": "Dropdown1",
|
"widgetName": "Dropdown1",
|
||||||
"defaultOptionValue": {
|
"defaultOptionValue": {
|
||||||
"value":"VEG",
|
"value":"VEG",
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@
|
||||||
"bottomRow": 23,
|
"bottomRow": 23,
|
||||||
"parentId": "anq2not518",
|
"parentId": "anq2not518",
|
||||||
"dynamicBindingPathList": [],
|
"dynamicBindingPathList": [],
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"dynamicTriggerPathList": []
|
"dynamicTriggerPathList": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -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]",
|
"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",
|
"optionLabel": "label",
|
||||||
"optionValue": "value",
|
"optionValue": "value",
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"placeholderText": "Select option",
|
"placeholderText": "Select option",
|
||||||
"isDisabled": false,
|
"isDisabled": false,
|
||||||
"key": "ber0u80gjl",
|
"key": "ber0u80gjl",
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@
|
||||||
"sourceData": "",
|
"sourceData": "",
|
||||||
"optionLabel": "label",
|
"optionLabel": "label",
|
||||||
"optionValue": "value",
|
"optionValue": "value",
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"isDisabled": false
|
"isDisabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@
|
||||||
"sourceData": "",
|
"sourceData": "",
|
||||||
"optionLabel": "label",
|
"optionLabel": "label",
|
||||||
"optionValue": "value",
|
"optionValue": "value",
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"widgetName": "Dropdown1",
|
"widgetName": "Dropdown1",
|
||||||
"type": "SELECT_WIDGET",
|
"type": "SELECT_WIDGET",
|
||||||
"isLoading": false,
|
"isLoading": false,
|
||||||
|
|
@ -135,6 +136,7 @@
|
||||||
"leftColumn": 10,
|
"leftColumn": 10,
|
||||||
"optionLable": "label",
|
"optionLable": "label",
|
||||||
"optionValue": "value",
|
"optionValue": "value",
|
||||||
|
"dynamicPropertyPathList": [{"key": "sourceData"}],
|
||||||
"sourceData": [
|
"sourceData": [
|
||||||
{
|
{
|
||||||
"label": "Hashirama Senju",
|
"label": "Hashirama Senju",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
"dropdownWidget": ".t--draggable-selectwidget",
|
"dropdownWidget": ".t--draggable-selectwidget",
|
||||||
"menuButtonWidget": ".t--draggable-menubuttonwidget",
|
"menuButtonWidget": ".t--draggable-menubuttonwidget",
|
||||||
"multiselectwidgetv2": ".t--draggable-multiselectwidgetv2",
|
"multiselectwidgetv2": ".t--draggable-multiselectwidgetv2",
|
||||||
|
"multiselectWidgetv2search": ".multi-select-dropdown .bp3-input",
|
||||||
"multiselecttreeWidget": ".t--draggable-multiselecttreewidget",
|
"multiselecttreeWidget": ".t--draggable-multiselecttreewidget",
|
||||||
"singleselecttreeWidget": ".t--draggable-singleselecttreewidget",
|
"singleselecttreeWidget": ".t--draggable-singleselecttreewidget",
|
||||||
"dropdownSelectionType": ".t--property-control-selectiontype .bp3-popover-target",
|
"dropdownSelectionType": ".t--property-control-selectiontype .bp3-popover-target",
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,6 @@ export default {
|
||||||
`[data-testid="t--one-click-binding-table-selector"] .rc-select-selection-item${
|
`[data-testid="t--one-click-binding-table-selector"] .rc-select-selection-item${
|
||||||
table ? `:contains(${table})` : ""
|
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:
|
validTableRowData:
|
||||||
'.t--widget-tablewidgetv2 [role="rowgroup"] [role="button"]',
|
'.t--widget-tablewidgetv2 [role="rowgroup"] [role="button"]',
|
||||||
tableError: (error: string) =>
|
tableError: (error: string) =>
|
||||||
|
|
@ -52,4 +42,16 @@ export default {
|
||||||
dayViewFromDate: ".DayPicker-Day",
|
dayViewFromDate: ".DayPicker-Day",
|
||||||
loadMore: "[data-testId='t--one-click-binding-datasource--load-more']",
|
loadMore: "[data-testId='t--one-click-binding-datasource--load-more']",
|
||||||
datasourceSearch: `[data-testId="t--one-click-binding-datasource--search"]`,
|
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})` : ""
|
||||||
|
}`,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -54,35 +54,10 @@ export default abstract class GSheets extends BaseQueryGenerator {
|
||||||
const { select } = widgetConfig;
|
const { select } = widgetConfig;
|
||||||
|
|
||||||
if (select && formConfig.sheetName) {
|
if (select && formConfig.sheetName) {
|
||||||
return {
|
const queryPayload: any = {
|
||||||
type: QUERY_TYPE.SELECT,
|
type: QUERY_TYPE.SELECT,
|
||||||
name: `Find_${removeSpecialChars(formConfig.sheetName)}`,
|
name: `Find_${removeSpecialChars(formConfig.sheetName)}`,
|
||||||
formData: {
|
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(
|
...this.buildBasicConfig(
|
||||||
COMMAND_TYPES.FIND,
|
COMMAND_TYPES.FIND,
|
||||||
formConfig.tableName,
|
formConfig.tableName,
|
||||||
|
|
@ -90,18 +65,56 @@ export default abstract class GSheets extends BaseQueryGenerator {
|
||||||
formConfig.tableHeaderIndex,
|
formConfig.tableHeaderIndex,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
dynamicBindingPathList: [
|
dynamicBindingPathList: [],
|
||||||
{
|
|
||||||
key: "formData.where.data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "formData.sortBy.data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "formData.pagination.data",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ describe("Mongo WidgetQueryGenerator", () => {
|
||||||
data: "{{data_table.pageSize}}",
|
data: "{{data_table.pageSize}}",
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
data: '{{{ title: {$regex: data_table.searchText||""} }}}',
|
data: `{{{ title: {$regex: data_table.searchText||"", '$options' : 'i'} }}}`,
|
||||||
},
|
},
|
||||||
skip: {
|
skip: {
|
||||||
data: "{{(data_table.pageNo - 1) * data_table.pageSize}}",
|
data: "{{(data_table.pageNo - 1) * data_table.pageSize}}",
|
||||||
|
|
@ -152,7 +152,7 @@ describe("Mongo WidgetQueryGenerator", () => {
|
||||||
data: "{{data_table.pageSize}}",
|
data: "{{data_table.pageSize}}",
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
data: '{{{ title: {$regex: data_table.searchText||""} }}}',
|
data: `{{{ title: {$regex: data_table.searchText||"", '$options' : 'i'} }}}`,
|
||||||
},
|
},
|
||||||
skip: {
|
skip: {
|
||||||
data: "{{(data_table.pageNo - 1) * data_table.pageSize}}",
|
data: "{{(data_table.pageNo - 1) * data_table.pageSize}}",
|
||||||
|
|
|
||||||
|
|
@ -30,39 +30,66 @@ export default abstract class MongoDB extends BaseQueryGenerator {
|
||||||
const { select } = widgetConfig;
|
const { select } = widgetConfig;
|
||||||
|
|
||||||
if (select) {
|
if (select) {
|
||||||
return {
|
const queryPayload: any = {
|
||||||
type: QUERY_TYPE.SELECT,
|
type: QUERY_TYPE.SELECT,
|
||||||
name: `Find_${removeSpecialChars(formConfig.tableName)}`,
|
name: `Find_${removeSpecialChars(formConfig.tableName)}`,
|
||||||
formData: {
|
formData: {
|
||||||
find: {
|
find: {
|
||||||
skip: { data: `{{${select["offset"]}}}` },
|
skip: { data: "" },
|
||||||
query: {
|
query: {
|
||||||
data: formConfig.searchableColumn
|
data: "",
|
||||||
? `{{{ ${formConfig.searchableColumn}: {$regex: ${select["where"]}} }}}`
|
|
||||||
: "",
|
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
data: `{{ ${select["orderBy"]} ? { [${select["orderBy"]}]: ${select["sortOrder"]} ? 1 : -1 } : {}}}`,
|
data: "",
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
data: "",
|
||||||
},
|
},
|
||||||
limit: { data: `{{${select["limit"]}}}` },
|
|
||||||
},
|
},
|
||||||
...this.buildBasicConfig(COMMAND_TYPES.FIND, formConfig.tableName),
|
...this.buildBasicConfig(COMMAND_TYPES.FIND, formConfig.tableName),
|
||||||
},
|
},
|
||||||
dynamicBindingPathList: [
|
dynamicBindingPathList: [],
|
||||||
{
|
|
||||||
key: "formData.find.skip.data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "formData.find.query.data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "formData.find.sort.data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "formData.find.limit.data",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ export type WidgetQueryGenerationFormConfig = {
|
||||||
|
|
||||||
export type WidgetQueryGenerationConfig = {
|
export type WidgetQueryGenerationConfig = {
|
||||||
select?: {
|
select?: {
|
||||||
limit: string;
|
limit?: string;
|
||||||
offset: string;
|
offset?: string;
|
||||||
where: string;
|
where?: string;
|
||||||
orderBy: string;
|
orderBy?: string;
|
||||||
sortOrder: string;
|
sortOrder?: string;
|
||||||
};
|
};
|
||||||
create?: {
|
create?: {
|
||||||
value: string;
|
value: string;
|
||||||
|
|
@ -31,7 +31,7 @@ export type WidgetQueryGenerationConfig = {
|
||||||
value: string;
|
value: string;
|
||||||
where?: string;
|
where?: string;
|
||||||
};
|
};
|
||||||
totalRecord: boolean;
|
totalRecord?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum QUERY_TYPE {
|
export enum QUERY_TYPE {
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,7 @@ function getWidgetProps(
|
||||||
{ key: "sourceData" },
|
{ key: "sourceData" },
|
||||||
{ key: "defaultOptionValue" },
|
{ key: "defaultOptionValue" },
|
||||||
],
|
],
|
||||||
|
dynamicPropertyPathList: [{ key: "sourceData" }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
case "TEXT_WIDGET":
|
case "TEXT_WIDGET":
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ export function useDatasource(searchText: string) {
|
||||||
onSourceClose,
|
onSourceClose,
|
||||||
propertyName,
|
propertyName,
|
||||||
propertyValue,
|
propertyValue,
|
||||||
|
sampleData,
|
||||||
updateConfig,
|
updateConfig,
|
||||||
widgetId,
|
widgetId,
|
||||||
} = useContext(WidgetQueryGeneratorFormContext);
|
} = useContext(WidgetQueryGeneratorFormContext);
|
||||||
|
|
@ -321,7 +322,7 @@ export function useDatasource(searchText: string) {
|
||||||
const { pageId: currentPageId } = useParams<ExplorerURLParams>();
|
const { pageId: currentPageId } = useParams<ExplorerURLParams>();
|
||||||
|
|
||||||
const otherOptions = useMemo(() => {
|
const otherOptions = useMemo(() => {
|
||||||
return [
|
const options = [
|
||||||
{
|
{
|
||||||
icon: <Icon name="plus" size="md" />,
|
icon: <Icon name="plus" size="md" />,
|
||||||
id: "Connect new datasource",
|
id: "Connect new datasource",
|
||||||
|
|
@ -350,7 +351,35 @@ export function useDatasource(searchText: string) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [currentPageId, history, propertyName]);
|
|
||||||
|
if (sampleData) {
|
||||||
|
options.push({
|
||||||
|
icon: <Icon name="code" size="md" />,
|
||||||
|
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);
|
const queries = useSelector(getActionsForCurrentPage);
|
||||||
|
|
||||||
|
|
@ -439,31 +468,47 @@ export function useDatasource(searchText: string) {
|
||||||
];
|
];
|
||||||
}, [searchText, datasourceOptions, otherOptions, queryOptions]);
|
}, [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 (
|
||||||
|
<DropdownOption
|
||||||
|
label={source?.label?.replace("sample ", "")}
|
||||||
|
leftIcon={source?.icon}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <Placeholder>Connect data</Placeholder>;
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
config,
|
||||||
|
datasourceOptions,
|
||||||
|
sampleData,
|
||||||
|
propertyValue,
|
||||||
|
otherOptions,
|
||||||
|
queryOptions,
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
datasourceOptions: filteredDatasourceOptions,
|
datasourceOptions: filteredDatasourceOptions,
|
||||||
otherOptions,
|
otherOptions,
|
||||||
selected: (() => {
|
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 (
|
|
||||||
<DropdownOption
|
|
||||||
label={source?.label?.replace("sample ", "")}
|
|
||||||
leftIcon={source?.icon}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return <Placeholder>Connect data</Placeholder>;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
queryOptions: filteredQueryOptions,
|
queryOptions: filteredQueryOptions,
|
||||||
isSourceOpen,
|
isSourceOpen,
|
||||||
onSourceClose,
|
onSourceClose,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||||
import type { AppState } from "@appsmith/reducers";
|
import type { AppState } from "@appsmith/reducers";
|
||||||
import { PluginPackageName } from "entities/Action";
|
import { PluginPackageName } from "entities/Action";
|
||||||
import { useContext } from "react";
|
import { useContext, useMemo } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { getWidget } from "sagas/selectors";
|
import { getWidget } from "sagas/selectors";
|
||||||
import { getPluginPackageFromDatasourceId } from "selectors/entitiesSelector";
|
import { getPluginPackageFromDatasourceId } from "selectors/entitiesSelector";
|
||||||
|
|
@ -14,7 +14,7 @@ import { useColumns } from "../WidgetSpecificControls/ColumnDropdown/useColumns"
|
||||||
export function useConnectData() {
|
export function useConnectData() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const { config, propertyName, widgetId } = useContext(
|
const { aliases, config, propertyName, widgetId } = useContext(
|
||||||
WidgetQueryGeneratorFormContext,
|
WidgetQueryGeneratorFormContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -27,16 +27,30 @@ export function useConnectData() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const onClick = () => {
|
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 = {
|
const payload = {
|
||||||
tableName: config.table,
|
tableName: config.table,
|
||||||
sheetName: config.sheet,
|
sheetName: config.sheet,
|
||||||
datasourceId: config.datasource,
|
datasourceId: config.datasource,
|
||||||
widgetId: widgetId,
|
widgetId: widgetId,
|
||||||
tableHeaderIndex: config.tableHeaderIndex,
|
tableHeaderIndex: config.tableHeaderIndex,
|
||||||
searchableColumn: config.searchableColumn,
|
searchableColumn,
|
||||||
columns: columns.map((column) => column.name),
|
columns: columns.map((column) => column.name),
|
||||||
primaryColumn,
|
primaryColumn,
|
||||||
connectionMode: config.datasourceConnectionMode,
|
connectionMode: config.datasourceConnectionMode,
|
||||||
|
aliases: Object.entries(config.alias).map(([key, value]) => ({
|
||||||
|
name: key,
|
||||||
|
alias: value,
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|
@ -54,6 +68,7 @@ export function useConnectData() {
|
||||||
additionalData: {
|
additionalData: {
|
||||||
dataTableName: config.table,
|
dataTableName: config.table,
|
||||||
searchableColumn: config.searchableColumn,
|
searchableColumn: config.searchableColumn,
|
||||||
|
alias: config.alias,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -64,10 +79,17 @@ export function useConnectData() {
|
||||||
|
|
||||||
const show = !!config.datasource;
|
const show = !!config.datasource;
|
||||||
|
|
||||||
const disabled =
|
const disabled = useMemo(() => {
|
||||||
!config.table ||
|
return (
|
||||||
(selectedDatasourcePluginPackageName === PluginPackageName.GOOGLE_SHEETS &&
|
!config.table ||
|
||||||
!isValidGsheetConfig(config));
|
(selectedDatasourcePluginPackageName ===
|
||||||
|
PluginPackageName.GOOGLE_SHEETS &&
|
||||||
|
!isValidGsheetConfig(config)) ||
|
||||||
|
aliases?.some((alias) => {
|
||||||
|
return alias.isRequired && !config.alias[alias.name];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}, [config, aliases]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show,
|
show,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { ErrorMessage, Label, SelectWrapper } from "../../styles";
|
||||||
import { useColumns } from "./useColumns";
|
import { useColumns } from "./useColumns";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
id: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
label: string;
|
label: string;
|
||||||
onSelect: () => void;
|
onSelect: () => void;
|
||||||
|
|
@ -29,7 +30,7 @@ function ColumnDropdown(props: Props) {
|
||||||
<Label>{props.label}</Label>
|
<Label>{props.label}</Label>
|
||||||
<Select
|
<Select
|
||||||
allowClear
|
allowClear
|
||||||
data-testId={`t--one-click-binding-column-${props.alias}`}
|
data-testId={`t--one-click-binding-column-${props.id}`}
|
||||||
dropdownStyle={{
|
dropdownStyle={{
|
||||||
minWidth: "350px",
|
minWidth: "350px",
|
||||||
maxHeight: "300px",
|
maxHeight: "300px",
|
||||||
|
|
@ -51,7 +52,7 @@ function ColumnDropdown(props: Props) {
|
||||||
{options.map((option) => {
|
{options.map((option) => {
|
||||||
return (
|
return (
|
||||||
<Option
|
<Option
|
||||||
data-testId={`t--one-click-binding-column-${props.alias}--column`}
|
data-testId={`t--one-click-binding-column-${props.id}--column`}
|
||||||
key={option.id}
|
key={option.id}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import type { AppState } from "@appsmith/reducers";
|
||||||
import { Icon } from "design-system";
|
import { Icon } from "design-system";
|
||||||
import { PluginPackageName } from "entities/Action";
|
import { PluginPackageName } from "entities/Action";
|
||||||
import { get, isArray } from "lodash";
|
import { get, isArray } from "lodash";
|
||||||
import { ALLOWED_SEARCH_DATATYPE } from "pages/Editor/GeneratePage/components/constants";
|
|
||||||
import { useCallback, useContext, useMemo } from "react";
|
import { useCallback, useContext, useMemo } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
|
|
@ -70,28 +69,21 @@ export function useColumns(alias: string) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else if (isArray(columns)) {
|
} else if (isArray(columns)) {
|
||||||
return columns
|
return columns.map((column: any) => {
|
||||||
.filter((column: any) => {
|
return {
|
||||||
return (
|
id: column.name,
|
||||||
column.type &&
|
label: column.name,
|
||||||
ALLOWED_SEARCH_DATATYPE.includes(column.type.toLowerCase())
|
value: column.name,
|
||||||
);
|
subText: column.type,
|
||||||
})
|
icon: (
|
||||||
.map((column: any) => {
|
<Icon
|
||||||
return {
|
color="var(--ads-v2-color-fg)"
|
||||||
id: column.name,
|
name="layout-column-line"
|
||||||
label: column.name,
|
size="md"
|
||||||
value: column.name,
|
/>
|
||||||
subText: column.type,
|
),
|
||||||
icon: (
|
};
|
||||||
<Icon
|
});
|
||||||
color="var(--ads-v2-color-fg)"
|
|
||||||
name="layout-column-line"
|
|
||||||
size="md"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,48 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ColumnDropdown from "./ColumnDropdown";
|
import ColumnDropdown from "./ColumnDropdown";
|
||||||
import { noop } from "lodash";
|
import { noop } from "lodash";
|
||||||
|
import type { Alias } from "../types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
hasSearchableColumn?: boolean;
|
hasSearchableColumn?: boolean;
|
||||||
hasAliasPicker?: boolean;
|
aliases?: Alias[];
|
||||||
aliases?: string[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function WidgetSpecificControls(props: Props) {
|
export default function WidgetSpecificControls(props: Props) {
|
||||||
let searchableColumn = null;
|
let searchableColumn = null;
|
||||||
let aliasPicker = null;
|
let aliases = null;
|
||||||
|
|
||||||
if (props.hasSearchableColumn) {
|
if (props.hasSearchableColumn) {
|
||||||
searchableColumn = (
|
searchableColumn = (
|
||||||
<ColumnDropdown
|
<ColumnDropdown
|
||||||
alias="searchableColumn"
|
alias="searchableColumn"
|
||||||
|
id="searchableColumn"
|
||||||
label="Select a searchable column"
|
label="Select a searchable column"
|
||||||
onSelect={noop}
|
onSelect={noop}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.hasAliasPicker && props.aliases) {
|
if (props.aliases?.length) {
|
||||||
aliasPicker = props.aliases.map((alias) => {
|
aliases = props.aliases.map(({ name }) => {
|
||||||
<ColumnDropdown alias={`alias.${alias}`} label={alias} onSelect={noop} />;
|
const label = name.slice(0, 1).toUpperCase() + name.slice(1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ColumnDropdown
|
||||||
|
alias={`alias.${name}`}
|
||||||
|
id={name}
|
||||||
|
key={name}
|
||||||
|
label={label}
|
||||||
|
onSelect={noop}
|
||||||
|
/>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{searchableColumn}
|
{searchableColumn}
|
||||||
{aliasPicker}
|
{aliases}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import {
|
||||||
getOneClickBindingConfigForWidget,
|
getOneClickBindingConfigForWidget,
|
||||||
} from "selectors/oneClickBindingSelectors";
|
} from "selectors/oneClickBindingSelectors";
|
||||||
import { updateOneClickBindingOptionsVisibility } from "actions/oneClickBindingActions";
|
import { updateOneClickBindingOptionsVisibility } from "actions/oneClickBindingActions";
|
||||||
|
import type { Alias } from "./types";
|
||||||
|
|
||||||
type WidgetQueryGeneratorFormContextType = {
|
type WidgetQueryGeneratorFormContextType = {
|
||||||
widgetId: string;
|
widgetId: string;
|
||||||
|
|
@ -39,6 +40,8 @@ type WidgetQueryGeneratorFormContextType = {
|
||||||
onSourceClose: () => void;
|
onSourceClose: () => void;
|
||||||
errorMsg: string;
|
errorMsg: string;
|
||||||
expectedType: string;
|
expectedType: string;
|
||||||
|
sampleData: string;
|
||||||
|
aliases: Alias[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_CONFIG_VALUE = {
|
const DEFAULT_CONFIG_VALUE = {
|
||||||
|
|
@ -64,6 +67,8 @@ const DEFAULT_CONTEXT_VALUE = {
|
||||||
errorMsg: "",
|
errorMsg: "",
|
||||||
propertyName: "",
|
propertyName: "",
|
||||||
expectedType: "",
|
expectedType: "",
|
||||||
|
sampleData: "",
|
||||||
|
aliases: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WidgetQueryGeneratorFormContext =
|
export const WidgetQueryGeneratorFormContext =
|
||||||
|
|
@ -78,6 +83,9 @@ type Props = {
|
||||||
widgetId: string;
|
widgetId: string;
|
||||||
errorMsg: string;
|
errorMsg: string;
|
||||||
expectedType: string;
|
expectedType: string;
|
||||||
|
aliases: Alias[];
|
||||||
|
searchableColumn: boolean;
|
||||||
|
sampleData: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function WidgetQueryGeneratorForm(props: Props) {
|
function WidgetQueryGeneratorForm(props: Props) {
|
||||||
|
|
@ -86,11 +94,13 @@ function WidgetQueryGeneratorForm(props: Props) {
|
||||||
const [pristine, setPristine] = useState(true);
|
const [pristine, setPristine] = useState(true);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
aliases,
|
||||||
errorMsg,
|
errorMsg,
|
||||||
expectedType,
|
expectedType,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
propertyPath,
|
propertyPath,
|
||||||
propertyValue,
|
propertyValue,
|
||||||
|
sampleData,
|
||||||
widgetId,
|
widgetId,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
|
@ -197,6 +207,8 @@ function WidgetQueryGeneratorForm(props: Props) {
|
||||||
errorMsg,
|
errorMsg,
|
||||||
propertyName: propertyPath,
|
propertyName: propertyPath,
|
||||||
expectedType,
|
expectedType,
|
||||||
|
sampleData,
|
||||||
|
aliases,
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
config,
|
config,
|
||||||
|
|
@ -208,6 +220,8 @@ function WidgetQueryGeneratorForm(props: Props) {
|
||||||
onSourceClose,
|
onSourceClose,
|
||||||
errorMsg,
|
errorMsg,
|
||||||
propertyPath,
|
propertyPath,
|
||||||
|
sampleData,
|
||||||
|
aliases,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -221,7 +235,10 @@ function WidgetQueryGeneratorForm(props: Props) {
|
||||||
<WidgetQueryGeneratorFormContext.Provider value={contextValue}>
|
<WidgetQueryGeneratorFormContext.Provider value={contextValue}>
|
||||||
<CommonControls />
|
<CommonControls />
|
||||||
<DatasourceSpecificControls />
|
<DatasourceSpecificControls />
|
||||||
<WidgetSpecificControls hasSearchableColumn />
|
<WidgetSpecificControls
|
||||||
|
aliases={props.aliases}
|
||||||
|
hasSearchableColumn={props.searchableColumn}
|
||||||
|
/>
|
||||||
<ConnectData />
|
<ConnectData />
|
||||||
</WidgetQueryGeneratorFormContext.Provider>
|
</WidgetQueryGeneratorFormContext.Provider>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,9 @@ export interface DropdownOptionType {
|
||||||
onSelect?: (value: string, option: DropdownOptionType) => void;
|
onSelect?: (value: string, option: DropdownOptionType) => void;
|
||||||
data?: any;
|
data?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Alias {
|
||||||
|
name: string;
|
||||||
|
isSearcheable?: boolean;
|
||||||
|
isRequired?: boolean;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import WidgetQueryGeneratorForm from "components/editorComponents/WidgetQueryGeneratorForm";
|
import WidgetQueryGeneratorForm from "components/editorComponents/WidgetQueryGeneratorForm";
|
||||||
|
import type { Alias } from "components/editorComponents/WidgetQueryGeneratorForm/types";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type { ControlData, ControlProps } from "./BaseControl";
|
import type { ControlProps } from "./BaseControl";
|
||||||
import BaseControl from "./BaseControl";
|
import BaseControl from "./BaseControl";
|
||||||
class OneClickBindingControl extends BaseControl<OneClickBindingControlProps> {
|
class OneClickBindingControl extends BaseControl<OneClickBindingControlProps> {
|
||||||
constructor(props: OneClickBindingControlProps) {
|
constructor(props: OneClickBindingControlProps) {
|
||||||
|
|
@ -15,9 +16,15 @@ class OneClickBindingControl extends BaseControl<OneClickBindingControlProps> {
|
||||||
* Commenting out as we're not able to switch between the js modes without value being overwritten
|
* Commenting out as we're not able to switch between the js modes without value being overwritten
|
||||||
* with default value by platform
|
* with default value by platform
|
||||||
*/
|
*/
|
||||||
static canDisplayValueInUI(config: ControlData, value: any): boolean {
|
static canDisplayValueInUI(
|
||||||
// {{query1.data}}
|
config: OneClickBindingControlProps,
|
||||||
return /^{{[^.]*\.data}}$/gi.test(value);
|
value: any,
|
||||||
|
): boolean {
|
||||||
|
// {{query1.data}} || sample data
|
||||||
|
return (
|
||||||
|
/^{{[^.]*\.data}}$/gi.test(value) ||
|
||||||
|
config.controlConfig?.sampleData === value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static shouldValidateValueOnDynamicPropertyOff() {
|
static shouldValidateValueOnDynamicPropertyOff() {
|
||||||
|
|
@ -52,11 +59,14 @@ class OneClickBindingControl extends BaseControl<OneClickBindingControlProps> {
|
||||||
public render() {
|
public render() {
|
||||||
return (
|
return (
|
||||||
<WidgetQueryGeneratorForm
|
<WidgetQueryGeneratorForm
|
||||||
|
aliases={this.props.controlConfig.aliases}
|
||||||
errorMsg={this.getErrorMessage()}
|
errorMsg={this.getErrorMessage()}
|
||||||
expectedType={this.props.expected?.autocompleteDataType || ""}
|
expectedType={this.props.expected?.autocompleteDataType || ""}
|
||||||
onUpdate={this.onUpdatePropertyValue}
|
onUpdate={this.onUpdatePropertyValue}
|
||||||
propertyPath={this.props.propertyName}
|
propertyPath={this.props.propertyName}
|
||||||
propertyValue={this.props.propertyValue}
|
propertyValue={this.props.propertyValue}
|
||||||
|
sampleData={this.props.controlConfig.sampleData}
|
||||||
|
searchableColumn={this.props.controlConfig.searchableColumn}
|
||||||
widgetId={this.props.widgetProperties.widgetId}
|
widgetId={this.props.widgetProperties.widgetId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
@ -65,4 +75,10 @@ class OneClickBindingControl extends BaseControl<OneClickBindingControlProps> {
|
||||||
|
|
||||||
export default OneClickBindingControl;
|
export default OneClickBindingControl;
|
||||||
|
|
||||||
export type OneClickBindingControlProps = ControlProps;
|
export type OneClickBindingControlProps = ControlProps & {
|
||||||
|
controlConfig: {
|
||||||
|
aliases: Alias[];
|
||||||
|
searchableColumn: boolean;
|
||||||
|
sampleData: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,11 @@ function* BindWidgetToDatasource(
|
||||||
data: `{{${queryNameMap[QUERY_TYPE.SELECT]}.data}}`,
|
data: `{{${queryNameMap[QUERY_TYPE.SELECT]}.data}}`,
|
||||||
run: `{{
|
run: `{{
|
||||||
${queryNameMap[QUERY_TYPE.SELECT]}.run();
|
${queryNameMap[QUERY_TYPE.SELECT]}.run();
|
||||||
${queryNameMap[QUERY_TYPE.TOTAL_RECORD]}.run();
|
${
|
||||||
|
createdQueryNames.includes(queryNameMap[QUERY_TYPE.TOTAL_RECORD])
|
||||||
|
? queryNameMap[QUERY_TYPE.TOTAL_RECORD] + ".run()"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
}}`,
|
}}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ import { DynamicHeight } from "utils/WidgetFeatures";
|
||||||
import IconSVG from "./icon.svg";
|
import IconSVG from "./icon.svg";
|
||||||
import Widget from "./widget";
|
import Widget from "./widget";
|
||||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||||
|
import type { WidgetProps } from "widgets/BaseWidget";
|
||||||
|
import type {
|
||||||
|
WidgetQueryConfig,
|
||||||
|
WidgetQueryGenerationFormConfig,
|
||||||
|
} from "WidgetQueryGenerators/types";
|
||||||
|
|
||||||
export const CONFIG = {
|
export const CONFIG = {
|
||||||
features: {
|
features: {
|
||||||
|
|
@ -60,6 +65,22 @@ export const CONFIG = {
|
||||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||||
setterConfig: Widget.getSetterConfig(),
|
setterConfig: Widget.getSetterConfig(),
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
getQueryGenerationConfig: (widgetProps: WidgetProps) => {
|
||||||
|
return Widget.getQueryGenerationConfig(widgetProps);
|
||||||
|
},
|
||||||
|
getPropertyUpdatesForQueryBinding: (
|
||||||
|
queryConfig: WidgetQueryConfig,
|
||||||
|
widget: WidgetProps,
|
||||||
|
formConfig: WidgetQueryGenerationFormConfig,
|
||||||
|
) => {
|
||||||
|
return Widget.getPropertyUpdatesForQueryBinding(
|
||||||
|
queryConfig,
|
||||||
|
widget,
|
||||||
|
formConfig,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
autoLayout: {
|
autoLayout: {
|
||||||
disabledPropsDefaults: {
|
disabledPropsDefaults: {
|
||||||
labelPosition: LabelPosition.Top,
|
labelPosition: LabelPosition.Top,
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,46 @@ import {
|
||||||
getLabelValueKeyOptions,
|
getLabelValueKeyOptions,
|
||||||
valueKeyValidation,
|
valueKeyValidation,
|
||||||
} from "./propertyUtils";
|
} from "./propertyUtils";
|
||||||
|
import type {
|
||||||
|
WidgetQueryConfig,
|
||||||
|
WidgetQueryGenerationFormConfig,
|
||||||
|
} from "WidgetQueryGenerators/types";
|
||||||
|
|
||||||
class MultiSelectWidget extends BaseWidget<
|
class MultiSelectWidget extends BaseWidget<
|
||||||
MultiSelectWidgetProps,
|
MultiSelectWidgetProps,
|
||||||
WidgetState
|
WidgetState
|
||||||
> {
|
> {
|
||||||
|
static getQueryGenerationConfig(widget: WidgetProps) {
|
||||||
|
return {
|
||||||
|
select: {
|
||||||
|
where: `${widget.widgetName}.filterText`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPropertyUpdatesForQueryBinding(
|
||||||
|
queryConfig: WidgetQueryConfig,
|
||||||
|
widget: WidgetProps,
|
||||||
|
formConfig: WidgetQueryGenerationFormConfig,
|
||||||
|
) {
|
||||||
|
let modify;
|
||||||
|
|
||||||
|
if (queryConfig.select) {
|
||||||
|
modify = {
|
||||||
|
sourceData: queryConfig.select.data,
|
||||||
|
optionLabel: formConfig.aliases.find((d) => d.name === "label")?.alias,
|
||||||
|
optionValue: formConfig.aliases.find((d) => d.name === "value")?.alias,
|
||||||
|
defaultOptionValue: "",
|
||||||
|
serverSideFiltering: true,
|
||||||
|
onFilterUpdate: queryConfig.select.run,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
modify,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||||
return {
|
return {
|
||||||
"!doc":
|
"!doc":
|
||||||
|
|
@ -78,11 +113,33 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
"Takes in an array of objects to display options. Bind data from an API using {{}}",
|
"Takes in an array of objects to display options. Bind data from an API using {{}}",
|
||||||
propertyName: "sourceData",
|
propertyName: "sourceData",
|
||||||
label: "Source Data",
|
label: "Source Data",
|
||||||
controlType: "INPUT_TEXT",
|
controlType: "ONE_CLICK_BINDING_CONTROL",
|
||||||
|
controlConfig: {
|
||||||
|
aliases: [
|
||||||
|
{
|
||||||
|
name: "label",
|
||||||
|
isSearcheable: true,
|
||||||
|
isRequired: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value",
|
||||||
|
isRequired: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sampleData: JSON.stringify(
|
||||||
|
[
|
||||||
|
{ name: "Blue", code: "BLUE" },
|
||||||
|
{ name: "Green", code: "GREEN" },
|
||||||
|
{ name: "Red", code: "RED" },
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
isJSConvertible: true,
|
||||||
placeholderText: '[{ "label": "Option1", "value": "Option2" }]',
|
placeholderText: '[{ "label": "Option1", "value": "Option2" }]',
|
||||||
isBindProperty: true,
|
isBindProperty: true,
|
||||||
isTriggerProperty: false,
|
isTriggerProperty: false,
|
||||||
isJSConvertible: false,
|
|
||||||
validation: {
|
validation: {
|
||||||
type: ValidationTypes.ARRAY,
|
type: ValidationTypes.ARRAY,
|
||||||
params: {
|
params: {
|
||||||
|
|
@ -98,9 +155,10 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
helpText: "Sets the label of the option",
|
helpText:
|
||||||
|
"Choose or set a field from source data as the display label",
|
||||||
propertyName: "optionLabel",
|
propertyName: "optionLabel",
|
||||||
label: "Label",
|
label: "Label key",
|
||||||
controlType: "DROP_DOWN",
|
controlType: "DROP_DOWN",
|
||||||
customJSControl: "WRAPPED_CODE_EDITOR",
|
customJSControl: "WRAPPED_CODE_EDITOR",
|
||||||
controlConfig: {
|
controlConfig: {
|
||||||
|
|
@ -130,9 +188,9 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
additionalAutoComplete: getLabelValueAdditionalAutocompleteData,
|
additionalAutoComplete: getLabelValueAdditionalAutocompleteData,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
helpText: "Sets the value of the option",
|
helpText: "Choose or set a field from source data as the value",
|
||||||
propertyName: "optionValue",
|
propertyName: "optionValue",
|
||||||
label: "Value",
|
label: "Value key",
|
||||||
controlType: "DROP_DOWN",
|
controlType: "DROP_DOWN",
|
||||||
customJSControl: "WRAPPED_CODE_EDITOR",
|
customJSControl: "WRAPPED_CODE_EDITOR",
|
||||||
controlConfig: {
|
controlConfig: {
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,15 @@ import { LabelPosition } from "components/constants";
|
||||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||||
import { ResponsiveBehavior } from "utils/autoLayout/constants";
|
import { ResponsiveBehavior } from "utils/autoLayout/constants";
|
||||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||||
|
|
||||||
import IconSVG from "./icon.svg";
|
import IconSVG from "./icon.svg";
|
||||||
import Widget from "./widget";
|
import Widget from "./widget";
|
||||||
import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants";
|
import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants";
|
||||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||||
|
import type { WidgetProps } from "widgets/BaseWidget";
|
||||||
|
import type {
|
||||||
|
WidgetQueryConfig,
|
||||||
|
WidgetQueryGenerationFormConfig,
|
||||||
|
} from "WidgetQueryGenerators/types";
|
||||||
|
|
||||||
export const CONFIG = {
|
export const CONFIG = {
|
||||||
features: {
|
features: {
|
||||||
|
|
@ -62,6 +66,20 @@ export const CONFIG = {
|
||||||
setterConfig: Widget.getSetterConfig(),
|
setterConfig: Widget.getSetterConfig(),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getQueryGenerationConfig: (widgetProps: WidgetProps) => {
|
||||||
|
return Widget.getQueryGenerationConfig(widgetProps);
|
||||||
|
},
|
||||||
|
getPropertyUpdatesForQueryBinding: (
|
||||||
|
queryConfig: WidgetQueryConfig,
|
||||||
|
widget: WidgetProps,
|
||||||
|
formConfig: WidgetQueryGenerationFormConfig,
|
||||||
|
) => {
|
||||||
|
return Widget.getPropertyUpdatesForQueryBinding(
|
||||||
|
queryConfig,
|
||||||
|
widget,
|
||||||
|
formConfig,
|
||||||
|
);
|
||||||
|
},
|
||||||
getSnipingModeUpdates: (
|
getSnipingModeUpdates: (
|
||||||
propValueMap: SnipingModeProperty,
|
propValueMap: SnipingModeProperty,
|
||||||
): PropertyUpdates[] => {
|
): PropertyUpdates[] => {
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,47 @@ import {
|
||||||
getLabelValueKeyOptions,
|
getLabelValueKeyOptions,
|
||||||
valueKeyValidation,
|
valueKeyValidation,
|
||||||
} from "./propertyUtils";
|
} from "./propertyUtils";
|
||||||
|
import type {
|
||||||
|
WidgetQueryConfig,
|
||||||
|
WidgetQueryGenerationFormConfig,
|
||||||
|
} from "WidgetQueryGenerators/types";
|
||||||
|
|
||||||
class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
constructor(props: SelectWidgetProps) {
|
constructor(props: SelectWidgetProps) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getQueryGenerationConfig(widget: WidgetProps) {
|
||||||
|
return {
|
||||||
|
select: {
|
||||||
|
where: `${widget.widgetName}.filterText`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPropertyUpdatesForQueryBinding(
|
||||||
|
queryConfig: WidgetQueryConfig,
|
||||||
|
widget: WidgetProps,
|
||||||
|
formConfig: WidgetQueryGenerationFormConfig,
|
||||||
|
) {
|
||||||
|
let modify;
|
||||||
|
|
||||||
|
if (queryConfig.select) {
|
||||||
|
modify = {
|
||||||
|
sourceData: queryConfig.select.data,
|
||||||
|
optionLabel: formConfig.aliases.find((d) => d.name === "label")?.alias,
|
||||||
|
optionValue: formConfig.aliases.find((d) => d.name === "value")?.alias,
|
||||||
|
defaultOptionValue: "",
|
||||||
|
serverSideFiltering: true,
|
||||||
|
onFilterUpdate: queryConfig.select.run,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
modify,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||||
return {
|
return {
|
||||||
"!doc":
|
"!doc":
|
||||||
|
|
@ -79,7 +114,30 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
"Takes in an array of objects to display options. Bind data from an API using {{}}",
|
"Takes in an array of objects to display options. Bind data from an API using {{}}",
|
||||||
propertyName: "sourceData",
|
propertyName: "sourceData",
|
||||||
label: "Source Data",
|
label: "Source Data",
|
||||||
controlType: "INPUT_TEXT",
|
controlType: "ONE_CLICK_BINDING_CONTROL",
|
||||||
|
controlConfig: {
|
||||||
|
aliases: [
|
||||||
|
{
|
||||||
|
name: "label",
|
||||||
|
isSearcheable: true,
|
||||||
|
isRequired: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value",
|
||||||
|
isRequired: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sampleData: JSON.stringify(
|
||||||
|
[
|
||||||
|
{ name: "Blue", code: "BLUE" },
|
||||||
|
{ name: "Green", code: "GREEN" },
|
||||||
|
{ name: "Red", code: "RED" },
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
isJSConvertible: true,
|
||||||
placeholderText: '[{ "label": "label1", "value": "value1" }]',
|
placeholderText: '[{ "label": "label1", "value": "value1" }]',
|
||||||
isBindProperty: true,
|
isBindProperty: true,
|
||||||
isTriggerProperty: false,
|
isTriggerProperty: false,
|
||||||
|
|
@ -98,9 +156,10 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
helpText: "Sets the label of the option",
|
helpText:
|
||||||
|
"Choose or set a field from source data as the display label",
|
||||||
propertyName: "optionLabel",
|
propertyName: "optionLabel",
|
||||||
label: "Label",
|
label: "Label key",
|
||||||
controlType: "DROP_DOWN",
|
controlType: "DROP_DOWN",
|
||||||
customJSControl: "WRAPPED_CODE_EDITOR",
|
customJSControl: "WRAPPED_CODE_EDITOR",
|
||||||
controlConfig: {
|
controlConfig: {
|
||||||
|
|
@ -131,9 +190,9 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
additionalAutoComplete: getLabelValueAdditionalAutocompleteData,
|
additionalAutoComplete: getLabelValueAdditionalAutocompleteData,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
helpText: "Sets the value of the option",
|
helpText: "Choose or set a field from source data as the value",
|
||||||
propertyName: "optionValue",
|
propertyName: "optionValue",
|
||||||
label: "Value",
|
label: "Value key",
|
||||||
controlType: "DROP_DOWN",
|
controlType: "DROP_DOWN",
|
||||||
customJSControl: "WRAPPED_CODE_EDITOR",
|
customJSControl: "WRAPPED_CODE_EDITOR",
|
||||||
controlConfig: {
|
controlConfig: {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ export default [
|
||||||
propertyName: "tableData",
|
propertyName: "tableData",
|
||||||
label: "Table data",
|
label: "Table data",
|
||||||
controlType: "ONE_CLICK_BINDING_CONTROL",
|
controlType: "ONE_CLICK_BINDING_CONTROL",
|
||||||
|
controlConfig: {
|
||||||
|
searchableColumn: true,
|
||||||
|
},
|
||||||
placeholderText: '[{ "name": "John" }]',
|
placeholderText: '[{ "name": "John" }]',
|
||||||
inputType: "ARRAY",
|
inputType: "ARRAY",
|
||||||
isBindProperty: true,
|
isBindProperty: true,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user