Build apps by connecting UI widgets to database queries or APIs. Write any logic in JS.
+
+Appsmith is a JavaScript-based visual development platform to build and launch internal tools quickly. Drag-and-drop pre-built widgets, and connect them using JavaScript to create interactive pages. Connect UI to your APIs and Databases to build complex workflows in minutes.
-
+**API Support**: REST APIs
+**Database Support**: PostgreSQL, MongoDB, MySQL, Redshift, Elastic Search, DynamoDB, Redis, & MSFT SQL Server
+**Hosting**: Cloud-hosted & On-premise
+
+Already familiar with Appsmith? [Quickly start building on your own](#%EF%B8%8F-quickstart).
-### Here's how you build something:
-1. Compose a page using pre-built UI components like table, charts, map viewers and forms.
-2. Connect the UI components to any REST API or databases like MySQL, Postgres, and MongoDB. Write any logic in JS.
-3. Deploy the internal tool to a custom URL and invite users to sign in with their Google accounts.
-
--------------------
-
-## ๐บ Demo Video
-
-* [Build a tool in 5 minutes!](http://bit.ly/appsmith-demo-github)
-
-## ๐ Example Applications
-
-* [Customer Support Dashboard](https://bit.ly/cs-dashboard-appsmith)
-* [Job Application Tracker](https://bit.ly/3hbYtTi)
-
-## ๐โโ๏ธ Getting Started
-You can try our online sandbox or deploy a Docker image on a server.
-* [Online sandbox](https://bit.ly/appsmith-signup-github)
-* [Deploy with Docker](https://bit.ly/appsmith-docker-github)
-
-## ๐ Why Appsmith?
-
-When we build internal tools today, we turn to admin panels, UI frameworks or use a bootstrap theme. We took inspirations from the best admin panels, bootstrap themes, and brought back the easy UI builder of Visual Basic.
-
-Appsmith is a quicker way of building internal tools by visualising them as modular blocks (**Widgets, APIs, Queries, JS**) and giving developers a simple user interface to configure them. Building new features, creating UI, changing dataflows, and modifying business logic becomes simpler because you no longer have to trudge through large undocumented code bases or wrestle with HTML/CSS.
-Appsmith doesn't take the fun out of coding, because it treats every block as an object and exposes it via javascript so that you can read, transform and manipulate it. Whether it's a widget, API or query, you get to decide where you need to configure using UI and where you need to code.
+
+
+
+
+
+
## ๐ญ Features
-* **5 minute setup**: Deploy Appsmith on your servers in 5 minutes.
-* **Build custom UI**: Drag & drop, resize and style widgets **without HTML / CSS**.
-* **Query data**: Query & update your database directly from the UI. Connect to **PostgreSQL, MongoDB, MySQL, REST & GraphQL APIs**.
-* **JS Logic**: Write snippets of business logic using JS to transform data, manipulate UI or trigger workflows. Use popular libraries like lodash & moment anywhere in the app
-* **Data Workflows**: Simple configuration to create flows when users interact with the UI.
-* **Realtime Editor**: Changes in your application reflect instantly with every edit. No need to compile!
-* **Works with existing, live databases**: Connect directly to any PostgreSQL, MySQL & MongoDB
-* **Fine-grained access control**: Control who can edit / view your applications from a single control panel
-* **App management**: Build and organise multiple applications on a single platform
+* **5-minute setup**: Deploy Appsmith on your server, or use our cloud version to start building in 5 minutes. [Quick Start](#%EF%B8%8F-quickstart)
+* **Frontend as a service**: Drag-and-drop to build sophisticated **dashboards** and **workflows, without writing HTML/CSS**. Write JavaScript anywhere to transform data, and dynamically control widget-properties.
+* **Database CRUD**: Query & update your database directly by connecting it to the UI. Connect to **PostgreSQL, MongoDB, MySQL & more!**
+* **Trigger APIs**: Connect to REST APIs to build custom apps.
+* **Security**: DB Credentials are AES 256 encrypted and no data is stored by appsmith. Deploy behind your private VPC for additional security!
+* **One-click deployment**: Managed deployment of your apps with a click of a button.
+* **Access-control**: Assign users different roles & control who can edit / view your applications.
+* **Supports OAuth**: Allow users to authenticate via Google Auth or GitHub Auth.
-## ๐ Documentation & Support
+## ๐บ Demo
-If you have encountered a bug or need to get in touch with us, you can contact us using one of the following channels:
+Unsure if Appsmith is for you? [Watch it in action here](http://bit.ly/appsmith-demo-github)
+But if youโd rather check out some real applications that can be built with Appsmith, check below:
+* [Customer Support Dashboard](https://bit.ly/cs-dashboard-appsmith)
+* [Job Application Tracker](https://bit.ly/3hbYtTi)
+
+## ๐โโ๏ธ Quickstart
+
+The following steps introduce you to building a simple user-list dashboard on Appsmith.
+1. [Sign up on Appsmith Cloud](https://bit.ly/appsmith-signup-github) or [Deploy Appsmith via Docker](https://bit.ly/appsmith-docker-github).
+2. Create a new app within the organization that has already been created for you.
+3. Click on the `+` icon next to the `Queries` section to add a new query in the mock database
+ 1. Name the query `usersQuery`.
+ 2. Write the query `select * from users limit 5;`.
+ 3. Run the query.
+ 4. In query window, switch to the `Settings` tab, and enable `Run Query on Page Load`.
+4. Click on the `+` icon next to the `Widgets` section and drag a table onto the screen
+5. Link the table data property to the `usersQuery` using JavaScript `{{usersQuery.data}}`
+6. Hit the Deploy button and checkout the view mode of the app.
+
+Congratulations ๐ You just built your first app on Appsmith!
+Connect your own data to build apps for your team. [Read more here.](https://docs.appsmith.com/core-concepts/connecting-to-databases)
+
+## ๐ Support & Troubleshooting
+
+If you encountered a bug or need help troubleshooting an issue, you can use one of the following channels:
+
+* Self Help: [Documentation](https://docs.appsmith.com/)
+* Community Support: [Discord](https://discord.gg/rBTTVJp)
* Issue & bug tracking: [GitHub Issues](https://github.com/appsmithorg/appsmith/issues/new/choose)
-* Community & Support: [Discord](https://discord.gg/rBTTVJp)
-* Documentation: [Documentation](https://docs.appsmith.com)
-We are committed to fostering an open and welcoming environment in the community. Please see the [Code of Conduct](CODE_OF_CONDUCT.md).
+## ๐งโ๐คโ๐ง Contributing
-## โ Contributing to Appsmith
+If you're interested in contributing to Appsmith:
+1. Start by reading our [Contribution Guide](https://github.com/appsmithorg/appsmith/blob/master/CONTRIBUTING.md).
+2. Learn how to set up your local environment, in our [developer-guide](https://github.com/appsmithorg/appsmith/blob/master/contributions/CodeContributionsGuidelines.md#-setup-for-local-development).
+3. Explore our list of [good first issues](https://github.com/appsmithorg/appsmith/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+First+Issue%22).
-Read our [Contribution Guide](https://github.com/appsmithorg/appsmith/blob/master/CONTRIBUTING.md) and join our community of contributors!
+We are committed to fostering an open and welcoming environment in the community. Please read our [Code of Conduct](CODE_OF_CONDUCT.md).
## ๐ License
The Appsmith platform is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) (Apache-2.0).
-## ๐งโ๐คโ๐ง Contributors
+## Contributors
-
+
diff --git a/app/client/README.old.md b/app/client/README.old.md
index 9bc8469e36..353e626643 100644
--- a/app/client/README.old.md
+++ b/app/client/README.old.md
@@ -1,6 +1,6 @@
**Edit a file, create a new file, and clone from Bitbucket in under 2 minutes**
-When you're done, you can delete the content in this README and update the file with details for others getting started with your repository.
+When you're done, you can delete the content in this README and then update the file with details for others getting started with your repository.
*We recommend that you open this README in another tab as you perform the tasks below. You can [watch our video](https://youtu.be/0ocf7u76WSo) for a full demo of all the steps in this tutorial. Open the video in a new tab to avoid leaving Bitbucket.*
diff --git a/app/client/cypress/fixtures/buttondsl.json b/app/client/cypress/fixtures/buttondsl.json
new file mode 100644
index 0000000000..4e125772d4
--- /dev/null
+++ b/app/client/cypress/fixtures/buttondsl.json
@@ -0,0 +1,42 @@
+{
+ "dsl": {
+ "widgetName": "MainContainer",
+ "backgroundColor": "none",
+ "rightColumn": 1224,
+ "snapColumns": 16,
+ "detachFromLayout": true,
+ "widgetId": "0",
+ "topRow": 0,
+ "bottomRow": 1280,
+ "containerStyle": "none",
+ "snapRows": 33,
+ "parentRowSpace": 1,
+ "type": "CANVAS_WIDGET",
+ "canExtend": true,
+ "dynamicBindings": {},
+ "version": 6,
+ "minHeight": 1292,
+ "parentColumnSpace": 1,
+ "leftColumn": 0,
+ "children": [
+ {
+ "isVisible": true,
+ "text": "Submit",
+ "buttonStyle": "PRIMARY_BUTTON",
+ "widgetName": "Button1",
+ "isDisabled": false,
+ "isDefaultClickDisabled": true,
+ "type": "BUTTON_WIDGET",
+ "isLoading": false,
+ "parentColumnSpace": 74,
+ "parentRowSpace": 40,
+ "leftColumn": 5,
+ "rightColumn": 7,
+ "topRow": 2,
+ "bottomRow": 3,
+ "parentId": "0",
+ "widgetId": "3qg87le9t4"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/client/cypress/fixtures/containerdsl.json b/app/client/cypress/fixtures/containerdsl.json
new file mode 100644
index 0000000000..fb7627a974
--- /dev/null
+++ b/app/client/cypress/fixtures/containerdsl.json
@@ -0,0 +1,61 @@
+{
+ "dsl": {
+ "widgetName": "MainContainer",
+ "backgroundColor": "none",
+ "rightColumn": 1224,
+ "snapColumns": 16,
+ "detachFromLayout": true,
+ "widgetId": "0",
+ "topRow": 0,
+ "bottomRow": 1280,
+ "containerStyle": "none",
+ "snapRows": 33,
+ "parentRowSpace": 1,
+ "type": "CANVAS_WIDGET",
+ "canExtend": true,
+ "dynamicBindings": {},
+ "version": 6,
+ "minHeight": 1292,
+ "parentColumnSpace": 1,
+ "leftColumn": 0,
+ "children": [
+ {
+ "isVisible": true,
+ "backgroundColor": "#FFFFFF",
+ "widgetName": "Container1",
+ "containerStyle": "card",
+ "children": [
+ {
+ "isVisible": true,
+ "widgetName": "Canvas1",
+ "containerStyle": "none",
+ "canExtend": false,
+ "detachFromLayout": true,
+ "children": [],
+ "minHeight": 400,
+ "type": "CANVAS_WIDGET",
+ "isLoading": false,
+ "parentColumnSpace": 1,
+ "parentRowSpace": 1,
+ "leftColumn": 0,
+ "rightColumn": 592,
+ "topRow": 0,
+ "bottomRow": 400,
+ "parentId": "76mznwu5lq",
+ "widgetId": "tik1oqc468"
+ }
+ ],
+ "type": "CONTAINER_WIDGET",
+ "isLoading": false,
+ "parentColumnSpace": 74,
+ "parentRowSpace": 40,
+ "leftColumn": 3,
+ "rightColumn": 11,
+ "topRow": 16,
+ "bottomRow": 26,
+ "parentId": "0",
+ "widgetId": "76mznwu5lq"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/client/cypress/fixtures/inputdsl.json b/app/client/cypress/fixtures/inputdsl.json
new file mode 100644
index 0000000000..c4379f1a51
--- /dev/null
+++ b/app/client/cypress/fixtures/inputdsl.json
@@ -0,0 +1,40 @@
+{
+ "dsl": {
+ "widgetName": "MainContainer",
+ "backgroundColor": "none",
+ "rightColumn": 1224,
+ "snapColumns": 16,
+ "detachFromLayout": true,
+ "widgetId": "0",
+ "topRow": 0,
+ "bottomRow": 1280,
+ "containerStyle": "none",
+ "snapRows": 33,
+ "parentRowSpace": 1,
+ "type": "CANVAS_WIDGET",
+ "canExtend": true,
+ "dynamicBindings": {},
+ "version": 6,
+ "minHeight": 1292,
+ "parentColumnSpace": 1,
+ "leftColumn": 0,
+ "children": [
+ {
+ "isVisible": true,
+ "inputType": "TEXT",
+ "label": "",
+ "widgetName": "Input1",
+ "type": "INPUT_WIDGET",
+ "isLoading": false,
+ "parentColumnSpace": 74,
+ "parentRowSpace": 40,
+ "leftColumn": 2,
+ "rightColumn": 7,
+ "topRow": 0,
+ "bottomRow": 1,
+ "parentId": "0",
+ "widgetId": "2lhsjdd5sg"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/client/cypress/fixtures/testdata.json b/app/client/cypress/fixtures/testdata.json
index cdd21b19bc..e7ff6ff21a 100644
--- a/app/client/cypress/fixtures/testdata.json
+++ b/app/client/cypress/fixtures/testdata.json
@@ -172,5 +172,7 @@
"productName": "Avocado Panini",
"orderAmount": 7.99
}
- ]
+ ],
+ "addInputWidgetBinding": "{{Table1.selectedRow.date",
+ "externalPage": "https://www.appsmith.com/"
}
\ No newline at end of file
diff --git a/app/client/cypress/integration/Smoke_TestSuite/Applications/UpdateApplication_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Applications/UpdateApplication_spec.js
new file mode 100644
index 0000000000..b46e2399ee
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/Applications/UpdateApplication_spec.js
@@ -0,0 +1,70 @@
+const homePage = require("../../../locators/HomePage.json");
+const commonlocators = require("../../../locators/commonlocators.json");
+import tinycolor from "tinycolor2";
+
+describe("Update Application", function() {
+ let appname;
+ let iconname;
+ let colorname;
+
+ it("Open the application menu and update name and then check whether update is reflected in the application card", function() {
+ cy.get(commonlocators.homeIcon).click({ force: true });
+ appname = localStorage.getItem("AppName");
+ cy.get(homePage.searchInput).type(appname);
+ cy.wait(2000);
+
+ cy.get(homePage.applicationCard)
+ .first()
+ .trigger("mouseover");
+ cy.get(homePage.appMoreIcon)
+ .first()
+ .click({ force: true });
+ cy.get(homePage.applicationName).type(appname + "{enter}");
+ cy.wait("@updateApplication").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get(homePage.applicationCardName).should("contain", appname);
+ });
+
+ it("Open the application menu and update icon and then check whether update is reflected in the application card", function() {
+ cy.get(homePage.applicationIconSelector)
+ .first()
+ .click();
+ cy.wait("@updateApplication")
+ .then(xhr => {
+ iconname = xhr.response.body.data.icon;
+ })
+ .should("have.nested.property", "response.body.responseMeta.status", 200);
+ cy.get(homePage.applicationCard)
+ .first()
+ .within(() => {
+ cy.get("a")
+ .invoke("attr", "name")
+ .should("equal", iconname);
+ });
+ });
+
+ it("Open the application menu and update card color and then check whether update is reflected in the application card", function() {
+ cy.get(homePage.applicationColorSelector)
+ .first()
+ .click();
+ cy.wait("@updateApplication")
+ .then(xhr => {
+ colorname = tinycolor(xhr.response.body.data.color).toRgbString();
+ })
+ .should("have.nested.property", "response.body.responseMeta.status", 200);
+ cy.wait(2000);
+
+ cy.get(homePage.applicationCard)
+ .first()
+ .within(() => {
+ cy.get(homePage.applicationBackgroundColor).should(
+ "have.css",
+ "background-color",
+ colorname,
+ );
+ });
+ });
+});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/Binding/ButtonWidgets_NavigateTo_validation_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Binding/ButtonWidgets_NavigateTo_validation_spec.js
new file mode 100644
index 0000000000..14a8ad64c3
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/Binding/ButtonWidgets_NavigateTo_validation_spec.js
@@ -0,0 +1,43 @@
+const commonlocators = require("../../../locators/commonlocators.json");
+const formWidgetsPage = require("../../../locators/FormWidgets.json");
+const dsl = require("../../../fixtures/buttondsl.json");
+const pages = require("../../../locators/Pages.json");
+const widgetsPage = require("../../../locators/Widgets.json");
+const publish = require("../../../locators/publishWidgetspage.json");
+const testdata = require("../../../fixtures/testdata.json");
+const dsl2 = require("../../../fixtures/displayWidgetDsl.json");
+const explorer = require("../../../locators/explorerlocators.json");
+
+describe("Binding the button Widgets and validating NavigateTo Page functionality", function() {
+ before(() => {
+ cy.addDsl(dsl);
+ });
+
+ it("Button widget with action navigate to page", function() {
+ cy.openPropertyPane("buttonwidget");
+ cy.get(widgetsPage.actionSelect).click();
+ cy.get(commonlocators.chooseAction)
+ .children()
+ .contains("Navigate To")
+ .click();
+ cy.enterActionValue(testdata.externalPage);
+ cy.get(commonlocators.editPropCrossButton).click();
+ cy.wait(300);
+ });
+
+ it("Button click should take the control to page link validation", function() {
+ cy.PublishtheApp();
+ cy.get(publish.buttonWidget).click();
+ cy.wait(500);
+ cy.get(publish.buttonWidget).should("not.be.visible");
+ cy.go("back");
+ cy.get(publish.backToEditor)
+ .first()
+ .click();
+ cy.wait("@getPage").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ });
+});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/Datasources/PostgresDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Datasources/PostgresDatasource_spec.js
index c70aaf4367..fc223533cd 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/Datasources/PostgresDatasource_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/Datasources/PostgresDatasource_spec.js
@@ -31,8 +31,6 @@ describe("Postgres datasource test cases", function() {
200,
);
- cy.GlobalSearchEntity(`${datasourceName}`);
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
- cy.deleteDataSource();
+ cy.deletePostgresDatasource(datasourceName);
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_API_Pane_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_API_Pane_spec.js
index 8e545ee661..437ad1416e 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_API_Pane_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_API_Pane_spec.js
@@ -9,13 +9,7 @@ describe("Entity explorer API pane related testcases", function() {
cy.NavigateToWidgetsInExplorer();
cy.get(explorer.NoWidgetsMsg).should("be.visible");
cy.NavigateToAPI_Panel();
- cy.get(explorer.NoApiMsg)
- .should("be.visible")
- .should("be.visible");
cy.NavigateToQueriesInExplorer();
- cy.get(explorer.NoQueryMsg)
- .should("be.visible")
- .should("be.visible");
cy.reload();
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js
index c3c10b3135..bd44eb457d 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js
@@ -74,11 +74,12 @@ describe("Entity explorer tests related to copy query", function() {
});
it("Delete query and rename datasource in explorer", function() {
- cy.deleteQuery();
cy.get(commonlocators.entityExplorersearch).clear();
cy.NavigateToDatasourceEditor();
cy.GlobalSearchEntity(`${datasourceName}`);
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
+ cy.get(`.t--entity-name:contains(${datasourceName})`)
+ .last()
+ .click();
cy.generateUUID().then(uid => {
updatedName = uid;
cy.log("complete uid :" + updatedName);
@@ -86,7 +87,6 @@ describe("Entity explorer tests related to copy query", function() {
cy.log("sliced id :" + updatedName);
cy.EditEntityNameByDoubleClick(datasourceName, updatedName);
cy.SearchEntityandOpen(updatedName);
- cy.get(datasource.editDatasource).click();
cy.testSaveDatasource();
cy.hoverAndClick();
cy.get(apiwidget.delete).click({ force: true });
@@ -97,5 +97,8 @@ describe("Entity explorer tests related to copy query", function() {
409,
);
});
+
+ cy.SearchEntityandOpen("Query1Copy");
+ cy.deleteQuery();
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js
index fd3ae30c1e..9f36557f4d 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js
@@ -2,6 +2,7 @@ const explorer = require("../../../locators/explorerlocators.json");
const queryEditor = require("../../../locators/QueryEditor.json");
const queryLocators = require("../../../locators/QueryEditor.json");
const commonlocators = require("../../../locators/commonlocators.json");
+const apiwidget = require("../../../locators/apiWidgetslocator.json");
let datasourceName;
@@ -15,6 +16,23 @@ describe("Entity explorer datasource structure", function() {
});
it("Entity explorer datasource structure", function() {
+ cy.NavigateToQueryEditor();
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(queryLocators.createQuery)
+ .click();
+ cy.wait("@createNewApi").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 201,
+ );
+
+ cy.get(apiwidget.apiTxt)
+ .clear()
+ .type("MyQuery", { force: true })
+ .should("have.value", "MyQuery")
+ .blur();
+ cy.WaitAutoSave();
+
cy.GlobalSearchEntity(datasourceName);
cy.wait("@getDatasourceStructure").should(
"have.nested.property",
@@ -51,10 +69,27 @@ describe("Entity explorer datasource structure", function() {
200,
);
+ cy.GlobalSearchEntity("MyQuery");
+ cy.get(`.t--entity-name:contains(MyQuery)`).click();
+ cy.get(queryEditor.deleteQuery).click();
+ cy.wait("@deleteAction").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+
+ cy.get(commonlocators.entityExplorersearch).clear();
+
cy.deletePostgresDatasource(datasourceName);
});
it("Refresh datasource structure", function() {
+ cy.NavigateToQueryEditor();
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(queryLocators.createQuery)
+ .click();
+ cy.get(queryLocators.templateMenu).click();
+
cy.GlobalSearchEntity(datasourceName);
cy.get(`.t--entity.datasource:contains(${datasourceName})`)
.find(explorer.collapse)
@@ -68,12 +103,6 @@ describe("Entity explorer datasource structure", function() {
cy.get(commonlocators.entityExplorersearch).clear();
- cy.NavigateToQueryEditor();
- cy.contains(".t--datasource-name", datasourceName)
- .find(queryLocators.createQuery)
- .click();
- cy.get(queryLocators.templateMenu).click();
-
const tableName = Math.random()
.toString(36)
.replace(/[^a-z]+/g, "");
@@ -127,6 +156,8 @@ describe("Entity explorer datasource structure", function() {
"response.body.responseMeta.status",
200,
);
+
+ cy.get(commonlocators.entityExplorersearch).clear();
cy.deletePostgresDatasource(datasourceName);
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js
index 5bb8ed757c..db4e0b64cc 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js
@@ -4,8 +4,15 @@ const apiwidget = require("../../../locators/apiWidgetslocator.json");
const commonlocators = require("../../../locators/commonlocators.json");
const pageid = "MyPage";
+let datasourceName;
describe("Entity explorer tests related to query and datasource", function() {
+ before(() => {
+ cy.generateUUID().then(uid => {
+ datasourceName = uid;
+ });
+ });
+
it("Create a page/moveQuery/rename/delete in explorer", function() {
cy.NavigateToDatasourceEditor();
cy.get(datasource.PostgreSQL).click();
@@ -16,15 +23,17 @@ describe("Entity explorer tests related to query and datasource", function() {
cy.testSaveDatasource();
+ cy.get(".t--edit-datasource-name").click();
+ cy.get(".t--edit-datasource-name input")
+ .clear()
+ .type(datasourceName, { force: true })
+ .should("have.value", datasourceName)
+ .blur();
+
cy.NavigateToQueryEditor();
-
- cy.get("@createDatasource").then(httpResponse => {
- const datasourceName = httpResponse.response.body.data.name;
-
- cy.contains(".t--datasource-name", datasourceName)
- .find(queryLocators.createQuery)
- .click();
- });
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(queryLocators.createQuery)
+ .click();
cy.get("@getPluginForm").should(
"have.nested.property",
@@ -40,15 +49,11 @@ describe("Entity explorer tests related to query and datasource", function() {
cy.EvaluateCurrentValue("select * from users");
- cy.get("@createDatasource").then(httpResponse => {
- const datasourceName = httpResponse.response.body.data.name;
-
- cy.get(apiwidget.propertyList).then(function($lis) {
- expect($lis).to.have.length(3);
- expect($lis.eq(0)).to.contain("{{Query1.isLoading}}");
- expect($lis.eq(1)).to.contain("{{Query1.data}}");
- expect($lis.eq(2)).to.contain("{{Query1.run()}}");
- });
+ cy.get(apiwidget.propertyList).then(function($lis) {
+ expect($lis).to.have.length(3);
+ expect($lis.eq(0)).to.contain("{{Query1.isLoading}}");
+ expect($lis.eq(1)).to.contain("{{Query1.data}}");
+ expect($lis.eq(2)).to.contain("{{Query1.run()}}");
});
cy.Createpage(pageid);
cy.GlobalSearchEntity("Query1");
@@ -62,14 +67,17 @@ describe("Entity explorer tests related to query and datasource", function() {
cy.MoveAPIToPage(pageid);
cy.SearchEntityandOpen("MyQuery");
cy.runQuery();
+
cy.deleteQuery();
- cy.get(commonlocators.entityExplorersearch).clear();
- cy.NavigateToDatasourceEditor();
- cy.get("@createDatasource").then(httpResponse => {
- const datasourceName = httpResponse.response.body.data.name;
- cy.GlobalSearchEntity(`${datasourceName}`);
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
- });
- cy.deleteDataSource();
+
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(".t--edit-datasource")
+ .click();
+ cy.get(".t--delete-datasource").click();
+ cy.wait("@deleteDatasource").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Container_spec.js b/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Container_spec.js
index b5f310d718..56cc93725d 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Container_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Container_spec.js
@@ -1,6 +1,6 @@
const commonlocators = require("../../../locators/commonlocators.json");
const widgetsPage = require("../../../locators/Widgets.json");
-const dsl = require("../../../fixtures/layoutdsl.json");
+const dsl = require("../../../fixtures/containerdsl.json");
describe("Container Widget Functionality", function() {
before(() => {
diff --git a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/CreateOrgTests_spec.js b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/CreateOrgTests_spec.js
index 4f11d6e725..4c0f39bf6f 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/CreateOrgTests_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/CreateOrgTests_spec.js
@@ -29,7 +29,9 @@ describe("Create new org and share with a user", function() {
cy.wait(2000);
cy.get(homePage.appsContainer).contains(orgid);
cy.xpath(homePage.ShareBtn).should("not.exist");
- cy.get(homePage.applicationCard).trigger("mouseover");
+ cy.get(homePage.applicationCard)
+ .first()
+ .trigger("mouseover");
cy.get(homePage.appEditIcon).should("not.exist");
cy.launchApp(appid);
cy.LogOut();
@@ -62,7 +64,9 @@ describe("Create new org and share with a user", function() {
cy.xpath(homePage.ShareBtn)
.first()
.should("be.visible");
- cy.get(homePage.applicationCard).trigger("mouseover");
+ cy.get(homePage.applicationCard)
+ .first()
+ .trigger("mouseover");
cy.get(homePage.appEditIcon)
.first()
.click({ force: true });
diff --git a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/ShareAppTests_spec.js b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/ShareAppTests_spec.js
index d67219cb9c..48843ba430 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/ShareAppTests_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/ShareAppTests_spec.js
@@ -1,128 +1,129 @@
-// ///
-//
-// const homePage = require("../../../locators/HomePage.json");
-// const publish = require("../../../locators/publishWidgetspage.json");
-//
-// describe("Create new org and share with a user", function() {
-// let orgid;
-// let appid;
-// let currentUrl;
-//
-// it("create org and then share with a user from Application share option within application", function() {
-// cy.NavigateToHome();
-// cy.generateUUID().then(uid => {
-// orgid = uid;
-// appid = uid;
-// localStorage.setItem("OrgName", orgid);
-// cy.createOrg(orgid);
-// cy.CreateAppForOrg(orgid, appid);
-// cy.wait("@getPagesForApp").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.get("h2").contains("Drag and drop a widget here");
-// cy.get(homePage.shareApp).click();
-// cy.shareApp(Cypress.env("TESTUSERNAME1"), homePage.viewerRole);
-// });
-// cy.LogOut();
-// });
-//
-// it("login as invited user and then validate viewer privilage", function() {
-// cy.LogintoApp(Cypress.env("TESTUSERNAME1"), Cypress.env("TESTPASSWORD1"));
-// cy.get(homePage.searchInput).type(appid);
-// cy.wait(2000);
-// cy.get(homePage.appsContainer).contains(orgid);
-// cy.xpath(homePage.ShareBtn).should("not.exist");
-// cy.get(homePage.applicationCard).trigger("mouseover");
-// cy.get(homePage.appEditIcon).should("not.exist");
-// cy.launchApp(appid);
-// cy.LogOut();
-// });
-//
-// it("Enable public access to Application", function() {
-// cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
-// cy.visit("/applications");
-// cy.wait("@applications").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.SearchApp(appid);
-// cy.wait("@getPagesForApp").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.get("h2").contains("Drag and drop a widget here");
-// cy.get(homePage.shareApp).click();
-// cy.enablePublicAccess();
-// cy.PublishtheApp();
-// currentUrl = cy.url();
-// cy.url().then(url => {
-// currentUrl = url;
-// cy.log(currentUrl);
-// });
-// cy.get(publish.backToEditor).click();
-// cy.LogOut();
-// });
-//
-// it("login as uninvited user and then validate public access of Application", function() {
-// cy.LogintoApp(Cypress.env("TESTUSERNAME2"), Cypress.env("TESTPASSWORD2"));
-// cy.visit(currentUrl);
-// cy.wait("@getPagesForApp").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.get(publish.pageInfo)
-// .invoke("text")
-// .then(text => {
-// const someText = text;
-// expect(someText).to.equal("This page seems to be blank");
-// });
-// cy.LogOut();
-// });
-// it("login as Owner and disable public access", function() {
-// cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
-// cy.visit("/applications");
-// cy.wait("@applications").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.SearchApp(appid);
-// cy.wait("@getPagesForApp").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.get("h2").contains("Drag and drop a widget here");
-// cy.get(homePage.shareApp).click();
-// cy.enablePublicAccess();
-// cy.LogOut();
-// });
-//
-// it("login as uninvited user and then validate public access disable feature", function() {
-// cy.LogintoApp(Cypress.env("TESTUSERNAME2"), Cypress.env("TESTPASSWORD2"));
-// cy.visit(currentUrl);
-// cy.wait("@getPagesForApp").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 404,
-// );
-// cy.LogOut();
-// });
-//
-// it("login as owner and delete App ", function() {
-// cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
-// cy.visit("/applications");
-// cy.wait("@applications").should(
-// "have.nested.property",
-// "response.body.responseMeta.status",
-// 200,
-// );
-// cy.SearchApp(appid);
-// cy.get("#loading").should("not.exist");
-// });
-// });
+///
+
+const homePage = require("../../../locators/HomePage.json");
+const publish = require("../../../locators/publishWidgetspage.json");
+
+describe("Create new org and share with a user", function() {
+ let orgid;
+ let appid;
+ let currentUrl;
+
+ it("create org and then share with a user from Application share option within application", function() {
+ cy.NavigateToHome();
+ cy.generateUUID().then(uid => {
+ orgid = uid;
+ appid = uid;
+ localStorage.setItem("OrgName", orgid);
+ cy.createOrg(orgid);
+ cy.CreateAppForOrg(orgid, appid);
+ cy.wait("@getPagesForCreateApp").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get("h2").contains("Drag and drop a widget here");
+ cy.get(homePage.shareApp).click({ force: true });
+ cy.shareApp(Cypress.env("TESTUSERNAME1"), homePage.viewerRole);
+ });
+ cy.LogOut();
+ });
+
+ it("login as invited user and then validate viewer privilage", function() {
+ cy.LogintoApp(Cypress.env("TESTUSERNAME1"), Cypress.env("TESTPASSWORD1"));
+ cy.get(homePage.searchInput).type(appid);
+ cy.wait(2000);
+ cy.get(homePage.appsContainer).contains(orgid);
+ cy.xpath(homePage.ShareBtn).should("not.exist");
+ cy.get(homePage.applicationCard).trigger("mouseover");
+ cy.get(homePage.appEditIcon).should("not.exist");
+ cy.launchApp(appid);
+ cy.LogOut();
+ });
+
+ it("Enable public access to Application", function() {
+ cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
+ cy.visit("/applications");
+ cy.wait("@applications").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.SearchApp(appid);
+ cy.wait("@getPagesForCreateApp").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get("h2").contains("Drag and drop a widget here");
+ cy.get(homePage.shareApp).click();
+ cy.enablePublicAccess();
+ cy.PublishtheApp();
+ currentUrl = cy.url();
+ cy.url().then(url => {
+ currentUrl = url;
+ cy.log(currentUrl);
+ });
+ cy.get(publish.backToEditor).click();
+ cy.LogOut();
+ });
+
+ it("login as uninvited user and then validate public access of Application", function() {
+ cy.LogintoApp(Cypress.env("TESTUSERNAME2"), Cypress.env("TESTPASSWORD2"));
+ cy.visit(currentUrl);
+ cy.wait("@getPagesForViewApp").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get(publish.pageInfo)
+ .invoke("text")
+ .then(text => {
+ const someText = text;
+ expect(someText).to.equal("This page seems to be blank");
+ });
+ cy.LogOut();
+ });
+
+ it("login as Owner and disable public access", function() {
+ cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
+ cy.visit("/applications");
+ cy.wait("@applications").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.SearchApp(appid);
+ cy.wait("@getPagesForCreateApp").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get("h2").contains("Drag and drop a widget here");
+ cy.get(homePage.shareApp).click();
+ cy.enablePublicAccess();
+ cy.LogOut();
+ });
+
+ it("login as uninvited user and then validate public access disable feature", function() {
+ cy.LogintoApp(Cypress.env("TESTUSERNAME2"), Cypress.env("TESTPASSWORD2"));
+ cy.visit(currentUrl);
+ cy.wait("@viewApp").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 404,
+ );
+ cy.LogOut();
+ });
+
+ it("login as owner and delete App ", function() {
+ cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
+ cy.visit("/applications");
+ cy.wait("@applications").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.SearchApp(appid);
+ cy.get("#loading").should("not.exist");
+ });
+});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/UpdateOrgTests_spec.js b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/UpdateOrgTests_spec.js
new file mode 100644
index 0000000000..ad922ce41f
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/UpdateOrgTests_spec.js
@@ -0,0 +1,71 @@
+const homePage = require("../../../locators/HomePage.json");
+
+describe("Update Organization", function() {
+ let orgid;
+
+ it("Open the org general settings and update org name. The update should reflect in the org. It should also reflect in the org names on the left side and the org dropdown. ", function() {
+ cy.NavigateToHome();
+ cy.generateUUID().then(uid => {
+ orgid = uid;
+ localStorage.setItem("OrgName", orgid);
+ cy.createOrg(orgid);
+ cy.get(homePage.orgList.concat(orgid).concat(")"))
+ .scrollIntoView()
+ .should("be.visible")
+ .within(() => {
+ cy.get(".t--org-name")
+ .first()
+ .click();
+ });
+ cy.get(homePage.orgSettingOption).click();
+ });
+ cy.generateUUID().then(uid => {
+ orgid = uid;
+ localStorage.setItem("OrgName", orgid);
+ cy.get(homePage.orgNameInput).clear();
+ cy.get(homePage.orgNameInput).type(orgid);
+ cy.wait(2000);
+ cy.get(homePage.orgHeaderName).should("have.text", orgid);
+ });
+ cy.NavigateToHome();
+ cy.get(homePage.leftPanelContainer).within(() => {
+ cy.get("span").should(item => {
+ expect(item).to.contain.text(orgid);
+ });
+ });
+ });
+
+ it("Open the org general settings and update org email. The update should reflect in the org.", function() {
+ cy.get(homePage.orgList.concat(orgid).concat(")"))
+ .scrollIntoView()
+ .should("be.visible")
+ .within(() => {
+ cy.get(".t--org-name")
+ .first()
+ .click();
+ });
+ cy.get(homePage.orgSettingOption).click();
+ cy.get(homePage.orgEmailInput).clear();
+ cy.get(homePage.orgEmailInput).type(Cypress.env("TESTUSERNAME2"));
+ cy.wait("@updateOrganization").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get(homePage.orgEmailInput).should(
+ "have.value",
+ Cypress.env("TESTUSERNAME2"),
+ );
+ });
+
+ it("Open the org general settings and update org website. The update should reflect in the org.", function() {
+ cy.get(homePage.orgWebsiteInput).clear();
+ cy.get(homePage.orgWebsiteInput).type("demowebsite");
+ cy.wait("@updateOrganization").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get(homePage.orgWebsiteInput).should("have.value", "demowebsite");
+ });
+});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidgetTableAndBind_spec.js b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidgetTableAndBind_spec.js
new file mode 100644
index 0000000000..ac8ba866f3
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidgetTableAndBind_spec.js
@@ -0,0 +1,78 @@
+const queryLocators = require("../../../locators/QueryEditor.json");
+const queryEditor = require("../../../locators/QueryEditor.json");
+const dsl = require("../../../fixtures/inputdsl.json");
+const pages = require("../../../locators/Pages.json");
+const widgetsPage = require("../../../locators/Widgets.json");
+const publish = require("../../../locators/publishWidgetspage.json");
+const testdata = require("../../../fixtures/testdata.json");
+const commonlocators = require("../../../locators/commonlocators.json");
+
+let datasourceName;
+
+describe("Addwidget from Query and bind with other widgets", function() {
+ before(() => {
+ cy.addDsl(dsl);
+ });
+
+ it("Create a PostgresDataSource", () => {
+ cy.createPostgresDatasource();
+ cy.get("@createDatasource").then(httpResponse => {
+ datasourceName = httpResponse.response.body.data.name;
+ });
+ });
+
+ it("Create a query and populate response by choosing addWidget and validate in Table Widget", () => {
+ cy.NavigateToQueryEditor();
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(queryLocators.createQuery)
+ .click();
+ cy.get(queryLocators.templateMenu).click();
+ cy.get(".CodeMirror textarea")
+ .first()
+ .focus()
+ .type('SELECT * FROM public."covidCases" LIMIT 10;');
+ cy.wait(500);
+ cy.get(queryEditor.runQuery).click();
+ cy.wait("@postExecute").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ cy.get(".t--add-widget").click();
+ cy.SearchEntityandOpen("Table1");
+ cy.isSelectRow(1);
+ cy.readTabledataPublish("1", "0").then(tabData => {
+ const tabValue = tabData;
+ cy.log("the value is" + tabValue);
+ expect(tabValue).to.be.equal("2020-01-23");
+ });
+ });
+
+ it("Input widget test with default value from table widget", () => {
+ cy.SearchEntityandOpen("Input1");
+ cy.get(widgetsPage.defaultInput).type(testdata.addInputWidgetBinding);
+ cy.get(commonlocators.editPropCrossButton).click();
+ cy.wait("@updateLayout").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
+ });
+
+ it("validation of data displayed in input widget based on row data selected", function() {
+ cy.isSelectRow(1);
+ cy.readTabledataPublish("1", "0").then(tabData => {
+ const tabValue = tabData;
+ cy.log("the value is" + tabValue);
+ expect(tabValue).to.be.equal("2020-01-23");
+ cy.get(publish.inputWidget + " " + "input")
+ .first()
+ .invoke("attr", "value")
+ .should("contain", tabValue);
+ cy.get(publish.inputWidget + " " + "input")
+ .last()
+ .invoke("attr", "value")
+ .should("contain", tabValue);
+ });
+ });
+});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidget_spec.js b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidget_spec.js
index 4aa8a2605a..435f92c7f2 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidget_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/AddWidget_spec.js
@@ -22,16 +22,20 @@ describe("Add widget", function() {
.first()
.focus()
.type("select * from configs");
-
+ cy.wait(500);
cy.get(queryEditor.runQuery).click();
cy.wait("@postExecute").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
);
-
cy.get(".t--add-widget").click();
-
cy.SearchEntityandOpen("Table1");
+ cy.isSelectRow(1);
+ cy.readTabledataPublish("1", "0").then(tabData => {
+ const tabValue = tabData;
+ expect(tabValue).to.be.equal("5");
+ cy.log("the value is " + tabValue);
+ });
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/MongoDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/MongoDatasource_spec.js
index e013ec788f..92a10fa831 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/MongoDatasource_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/MongoDatasource_spec.js
@@ -2,6 +2,8 @@ const queryLocators = require("../../../locators/QueryEditor.json");
const plugins = require("../../../fixtures/plugins.json");
const datasource = require("../../../locators/DatasourcesEditor.json");
+let datasourceName;
+
describe("Create a query with a mongo datasource, run, save and then delete the query", function() {
it("Create a query with a mongo datasource, run, save and then delete the query", function() {
cy.NavigateToDatasourceEditor();
@@ -16,7 +18,7 @@ describe("Create a query with a mongo datasource, run, save and then delete the
cy.NavigateToQueryEditor();
cy.get("@createDatasource").then(httpResponse => {
- const datasourceName = httpResponse.response.body.data.name;
+ datasourceName = httpResponse.response.body.data.name;
cy.contains(".t--datasource-name", datasourceName)
.find(queryLocators.createQuery)
@@ -38,19 +40,10 @@ describe("Create a query with a mongo datasource, run, save and then delete the
cy.EvaluateCurrentValue(`{"find": "planets"}`);
cy.runAndDeleteQuery();
- cy.NavigateToDatasourceEditor();
cy.get("@createDatasource").then(httpResponse => {
- const datasourceName = httpResponse.response.body.data.name;
+ datasourceName = httpResponse.response.body.data.name;
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
+ cy.deletePostgresDatasource(datasourceName);
});
-
- cy.get(datasource.editDatasource).click();
- cy.get(".t--delete-datasource").click();
- cy.wait("@deleteDatasource").should(
- "have.nested.property",
- "response.body.responseMeta.status",
- 200,
- );
});
});
diff --git a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/PostgreDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/PostgreDatasource_spec.js
index f11014d18b..0d6ccc14a2 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/QueryPane/PostgreDatasource_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/QueryPane/PostgreDatasource_spec.js
@@ -48,9 +48,10 @@ describe("Create a query with a postgres datasource, run, save and then delete t
cy.runAndDeleteQuery();
});
it("Deletes a datasource", () => {
- cy.NavigateToDatasourceEditor();
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
- cy.get(datasource.editDatasource).click();
+ cy.NavigateToQueryEditor();
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(".t--edit-datasource")
+ .click();
cy.get(".t--delete-datasource").click();
cy.wait("@deleteDatasource").should(
diff --git a/app/client/cypress/integration/Smoke_TestSuite/UnitTest/LoginFromUIApp_spec.js b/app/client/cypress/integration/Smoke_TestSuite/UnitTest/LoginFromUIApp_spec.js
index 1453b4b428..67ff5a2732 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/UnitTest/LoginFromUIApp_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/UnitTest/LoginFromUIApp_spec.js
@@ -30,4 +30,20 @@ describe("Login from UI and check the functionality", function() {
cy.wait(500);
cy.url().should("include", "user/login");
});
+
+ it("Theme change test and validation", function() {
+ cy.LogintoApp(Cypress.env("USERNAME"), Cypress.env("PASSWORD"));
+ cy.get(homePage.profileMenu).click();
+ cy.get(homePage.themeText).should("have.attr", "value", "true");
+ cy.get("span")
+ .contains("Light")
+ .click({ force: true });
+ cy.get(homePage.profileMenu).click();
+ cy.get(homePage.themeText).should("have.attr", "value", "false");
+ cy.get("span")
+ .contains("Dark")
+ .click({ force: true });
+ cy.get(homePage.profileMenu).click();
+ cy.get(homePage.themeText).should("have.attr", "value", "true");
+ });
});
diff --git a/app/client/cypress/locators/ApiEditor.json b/app/client/cypress/locators/ApiEditor.json
index 0ba7c8ca51..b5e9c1dd11 100644
--- a/app/client/cypress/locators/ApiEditor.json
+++ b/app/client/cypress/locators/ApiEditor.json
@@ -4,7 +4,7 @@
"createBlankApiCard": ".t--createBlankApiCard",
"eachProviderCard": ".t--eachProviderCard",
"nameOfApi": ".t--nameOfApi",
- "ApiNameField": ".bp3-editable-text",
+ "ApiNameField": ".t--action-name-edit-field",
"addToPageBtn": ".t--addToPageBtn",
"ApiDeleteBtn": ".t--apiFormDeleteBtn",
"ApiRunBtn": ".t--apiFormRunBtn",
diff --git a/app/client/cypress/locators/DatasourcesEditor.json b/app/client/cypress/locators/DatasourcesEditor.json
index 9fd3710f5c..7360ed384c 100644
--- a/app/client/cypress/locators/DatasourcesEditor.json
+++ b/app/client/cypress/locators/DatasourcesEditor.json
@@ -13,7 +13,6 @@
"PostgreSQL": ".t--plugin-name:contains('PostgreSQL')",
"sectionAuthentication": "[data-cy=section-Authentication]",
"sectionSSL": "[data-cy=section-SSL\\ \\(optional\\)]",
- "addDatasourceEntity": ".plugins .t--entity-add-btn",
"PostgresEntity": ".t--entity-name:contains(PostgreSQL)",
"createQuerty": ".t--create-query",
"editDatasource": ".t--edit-datasource"
diff --git a/app/client/cypress/locators/HomePage.json b/app/client/cypress/locators/HomePage.json
index 4516962264..3a31c08531 100644
--- a/app/client/cypress/locators/HomePage.json
+++ b/app/client/cypress/locators/HomePage.json
@@ -45,10 +45,21 @@
"orgSection": "a:contains(",
"createAppFrOrg": ") .t--create-app-popup",
"shareApp": ".t--application-share-btn",
- "enablePublicAccess": ".bp3-control-indicator",
+ "enablePublicAccess": ".slider",
"closeBtn": ".bp3-dialog-close-button",
"applicationName": ".t--application-name",
"profileMenu": ".bp3-popover-wrapper.profile-menu",
"signOutIcon": ".t--logout-icon",
- "headerAppSmithLogo": ".t--Appsmith-logo-image"
-}
\ No newline at end of file
+ "headerAppSmithLogo": ".t--Appsmith-logo-image",
+ "applicationCardName": "[data-cy=t--app-card-name]",
+ "applicationIconSelector": ".t--icon-not-selected",
+ "applicationColorSelector": ".t--color-not-selected",
+ "applicationBackgroundColor": ".t--application-card-background",
+ "orgSettingOption": "[data-cy=t--org-setting]",
+ "orgNameInput": "[data-cy=t--org-name-input]",
+ "orgEmailInput": "[data-cy=t--org-email-input]",
+ "orgWebsiteInput": "[data-cy=t--org-website-input]",
+ "orgHeaderName": ".t--organization-header",
+ "leftPanelContainer": "[data-cy=t--left-panel]",
+ "themeText": "label div"
+}
diff --git a/app/client/cypress/locators/Pages.json b/app/client/cypress/locators/Pages.json
index 8ef9748aa0..206e7b874c 100644
--- a/app/client/cypress/locators/Pages.json
+++ b/app/client/cypress/locators/Pages.json
@@ -5,7 +5,7 @@
"viewWidgets": ".t--page-sidebar-ViewWidgets",
"widgetsEditor": ".t--nav-link-widgets-editor",
"AddPage": ".pages .t--entity-add-btn",
- "editInput": "input.bp3-editable-text-input",
+ "editInput": ".t--entity-name.editing",
"Menuaction": ".bp3-overlay-open>.bp3-transition-container",
"Delete": ":nth-child(2) > .bp3-menu-item",
"apiEditorIcon": ".t--nav-link-api-editor",
@@ -14,7 +14,7 @@
"entityTable": ".t--entity-name:contains('Table1')",
"entityText": ".t--entity-name:contains('Text1')",
"entityExplorer": ".t--nav-link-entity-explorer",
- "popover": "//div[contains(@class,'t--entity page')]//*[local-name()='g' and @id='Icon/Outline/more-vertical']",
+ "popover": "//div[contains(@class,'t--entity page')]//*[last()]//*[local-name()='g' and @id='Icon/Outline/more-vertical']",
"editName": ".single-select >div:contains('Edit Name')",
"clonePage": ".single-select >div:contains('Clone')",
"deletePage": ".single-select >div:contains('Delete')",
diff --git a/app/client/cypress/locators/QueryEditor.json b/app/client/cypress/locators/QueryEditor.json
index 64d78d0159..b5cb009914 100644
--- a/app/client/cypress/locators/QueryEditor.json
+++ b/app/client/cypress/locators/QueryEditor.json
@@ -5,5 +5,6 @@
"saveQuery": ".t--save-query",
"deleteQuery": ".t--delete-query",
"createQuery": ".t--create-query",
- "addQueryEntity": ".//div[contains(@class,'t--entity group queries')]//div[contains(@class,'t--entity-add-btn')]"
+ "addQueryEntity": ".//div[contains(@class,'t--entity group queries')]//div[contains(@class,'t--entity-add-btn')]",
+ "addDatasource": ".t--add-datasource"
}
diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json
index e782a531d4..e44bb52a71 100644
--- a/app/client/cypress/locators/commonlocators.json
+++ b/app/client/cypress/locators/commonlocators.json
@@ -30,7 +30,7 @@
"labelTextStyle": ".bp3-ui-text span",
"bodyTextStyle": ".bp3-running-text span",
"headingTextStyle": ".bp3-heading span",
- "editWidgetName": ".bp3-editable-text",
+ "editWidgetName": ".t--propery-page-title",
"dropDownIcon": ".t--property-control-textstyle span.bp3-icon-chevron-down",
"onDateSelectedField": ".t--property-control-ondateselected",
"TableRow": ".t--draggable-tablewidget .tbody",
diff --git a/app/client/cypress/locators/explorerlocators.json b/app/client/cypress/locators/explorerlocators.json
index 938a57bfe0..23c42bc461 100644
--- a/app/client/cypress/locators/explorerlocators.json
+++ b/app/client/cypress/locators/explorerlocators.json
@@ -1,6 +1,6 @@
{
"NoApiMsg": "p:contains('No APIs yet.')",
- "NoQueryMsg": "p:contains('No Queries yet.')",
+ "NoQueryMsg": "p:contains('No DB Queries yet.')",
"NoWidgetsMsg": "p:contains('No widgets yet.')",
"AddPage": ".pages .t--entity-add-btn",
"addEntityAPI": ".apis .t--entity-add-btn",
@@ -24,5 +24,6 @@
"entity":".t--entity-name",
"addWidget":".widgets .t--entity-add-btn",
"dropHere":".appsmith_widget_0",
- "closeWidgets":".t--close-widgets-sidebar"
+ "closeWidgets":".t--close-widgets-sidebar",
+ "addDBQueryEntity": ".dbqueries .t--entity-add-btn"
}
\ No newline at end of file
diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js
index a747790c17..b32c1322ea 100644
--- a/app/client/cypress/support/commands.js
+++ b/app/client/cypress/support/commands.js
@@ -202,7 +202,7 @@ Cypress.Commands.add("launchApp", appName => {
.first()
.click();
cy.get("#loading").should("not.exist");
- cy.wait("@getPagesForApp").should(
+ cy.wait("@getPagesForViewApp").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
@@ -214,28 +214,37 @@ Cypress.Commands.add("CreateAppForOrg", (orgName, appname) => {
.scrollIntoView()
.should("be.visible")
.click();
- cy.get(homePage.inputAppName).type(appname);
- cy.get(homePage.CreateApp)
- .contains("Submit")
- .click({ force: true });
- cy.get("#loading").should("not.exist");
+ cy.wait("@createNewApplication").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 201,
+ );
+ cy.wait(1000);
+ cy.get(homePage.applicationName).type(appname + "{enter}");
+ cy.wait("@updateApplication").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 200,
+ );
});
Cypress.Commands.add("CreateApp", appname => {
cy.get(homePage.createNew)
.first()
.click({ force: true });
- cy.get(homePage.inputAppName).type(appname);
- cy.get(homePage.CreateApp)
- .contains("Submit")
- .click({ force: true });
+ cy.wait("@createNewApplication").should(
+ "have.nested.property",
+ "response.body.responseMeta.status",
+ 201,
+ );
cy.get("#loading").should("not.exist");
- cy.wait("@getPagesForApp").should(
+ cy.wait(1000);
+ cy.get(homePage.applicationName).type(appname + "{enter}");
+ cy.wait("@updateApplication").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
);
- cy.get("h2").contains("Drag and drop a widget here");
});
Cypress.Commands.add("DeleteApp", appName => {
@@ -301,7 +310,9 @@ Cypress.Commands.add("DeleteApp", appName => {
cy.get(commonlocators.homeIcon).click({ force: true });
cy.get(homePage.searchInput).type(appName);
cy.wait(2000);
- cy.get(homePage.applicationCard).trigger("mouseover");
+ cy.get(homePage.applicationCard)
+ .first()
+ .trigger("mouseover");
cy.get(homePage.appMoreIcon)
.first()
.click({ force: true });
@@ -552,9 +563,9 @@ Cypress.Commands.add("SearchEntityandOpen", apiname1 => {
cy.get(
commonlocators.entitySearchResult.concat(apiname1).concat("')"),
).should("be.visible");
- cy.get(
- commonlocators.entitySearchResult.concat(apiname1).concat("')"),
- ).click({ force: true });
+ cy.get(commonlocators.entitySearchResult.concat(apiname1).concat("')"))
+ .last()
+ .click({ force: true });
});
Cypress.Commands.add("enterDatasourceAndPath", (datasource, path) => {
@@ -723,7 +734,7 @@ Cypress.Commands.add("MoveAPIToPage", pageName => {
cy.get(apiwidget.page)
.contains(pageName)
.click();
- cy.wait("@saveAction").should(
+ cy.wait("@moveAction").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
@@ -1304,11 +1315,14 @@ Cypress.Commands.add("importCurl", () => {
});
Cypress.Commands.add("NavigateToDatasourceEditor", () => {
- cy.get(datasourceEditor.addDatasourceEntity).click({ force: true });
+ cy.get(explorer.addDBQueryEntity)
+ .last()
+ .click({ force: true });
+ cy.get(queryEditor.addDatasource).click();
});
Cypress.Commands.add("NavigateToQueryEditor", () => {
- cy.xpath(queryEditor.addQueryEntity).click({ force: true });
+ cy.get(explorer.addDBQueryEntity).click({ force: true });
});
Cypress.Commands.add("testDatasource", () => {
@@ -1390,9 +1404,11 @@ Cypress.Commands.add("createPostgresDatasource", () => {
});
Cypress.Commands.add("deletePostgresDatasource", datasourceName => {
- cy.NavigateToDatasourceEditor();
- cy.get(`.t--entity-name:contains(${datasourceName})`).click();
- cy.get(datasourceEditor.editDatasource).click();
+ cy.NavigateToQueryEditor();
+
+ cy.contains(".t--datasource-name", datasourceName)
+ .find(".t--edit-datasource")
+ .click();
cy.get(".t--delete-datasource").click();
cy.wait("@deleteDatasource").should(
"have.nested.property",
@@ -1591,7 +1607,9 @@ Cypress.Commands.add("startServerAndRoutes", () => {
cy.route("POST", "/api/v1/logout").as("postLogout");
cy.route("GET", "/api/v1/datasources").as("getDataSources");
- cy.route("GET", "/api/v1/pages/application/*").as("getPagesForApp");
+ cy.route("GET", "/api/v1/pages/application/*").as("getPagesForCreateApp");
+ cy.route("GET", "/api/v1/applications/view/*").as("getPagesForViewApp");
+
cy.route("POST");
cy.route("GET", "/api/v1/pages/*").as("getPage");
cy.route("GET", "/api/v1/actions*").as("getActions");
@@ -1640,8 +1658,9 @@ Cypress.Commands.add("startServerAndRoutes", () => {
cy.route("DELETE", "/api/v1/datasources/*").as("deleteDatasource");
cy.route("DELETE", "/api/v1/applications/*").as("deleteApplication");
cy.route("POST", "/api/v1/applications/?orgId=*").as("createNewApplication");
- cy.route("PUT", "/api/v1/applications/*").as("updateApplicationName");
+ cy.route("PUT", "/api/v1/applications/*").as("updateApplication");
cy.route("PUT", "/api/v1/actions/*").as("saveAction");
+ cy.route("PUT", "/api/v1/actions/move").as("moveAction");
cy.route("POST", "/api/v1/organizations").as("createOrg");
cy.route("POST", "/api/v1/users/invite").as("postInvite");
@@ -1652,6 +1671,9 @@ Cypress.Commands.add("startServerAndRoutes", () => {
cy.route("POST", "/api/v1/pages").as("createPage");
cy.route("POST", "/api/v1/pages/clone/*").as("clonePage");
cy.route("PUT", "/api/v1/applications/*/changeAccess").as("changeAccess");
+
+ cy.route("PUT", "/api/v1/organizations/*").as("updateOrganization");
+ cy.route("GET", "/api/v1/pages/view/application/*").as("viewApp");
});
Cypress.Commands.add("alertValidate", text => {
@@ -1777,15 +1799,3 @@ Cypress.Commands.add("callApi", apiname => {
Cypress.Commands.add("assertPageSave", () => {
cy.get(commonlocators.saveStatusSuccess);
});
-
-Cypress.Commands.add("EditApp", appName => {
- cy.get(homePage.searchInput).type(appName);
- cy.wait(2000);
- cy.get(homePage.applicationCard)
- .first()
- .trigger("mouseover");
- cy.get(homePage.appEditIcon)
- .first()
- .click({ force: true });
- cy.get("#loading").should("not.exist");
-});
diff --git a/app/client/docker/templates/nginx-mac.conf.template b/app/client/docker/templates/nginx-mac.conf.template
index 5ebbe8481e..e36919c4e8 100644
--- a/app/client/docker/templates/nginx-mac.conf.template
+++ b/app/client/docker/templates/nginx-mac.conf.template
@@ -46,21 +46,21 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
}
@@ -114,20 +114,20 @@ server {
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
- proxy_pass https://release-api.appsmith.com;
+ proxy_pass http://host.docker.internal:8080;
}
}
diff --git a/app/client/package.json b/app/client/package.json
index ae1cb29ab7..b766d9d8fe 100644
--- a/app/client/package.json
+++ b/app/client/package.json
@@ -102,6 +102,7 @@
"react-toastify": "^5.5.0",
"react-transition-group": "^4.3.0",
"react-use-gesture": "^7.0.4",
+ "react-zoom-pan-pinch": "^1.6.1",
"redux": "^4.0.1",
"redux-form": "^8.2.6",
"redux-saga": "^1.1.3",
diff --git a/app/client/src/AppRouter.tsx b/app/client/src/AppRouter.tsx
index 2b9daf0615..fb0bd5ef32 100644
--- a/app/client/src/AppRouter.tsx
+++ b/app/client/src/AppRouter.tsx
@@ -36,13 +36,15 @@ import { connect } from "react-redux";
import * as Sentry from "@sentry/react";
import AnalyticsUtil from "utils/AnalyticsUtil";
+import { trimTrailingSlash } from "utils/helpers";
+
const SentryRoute = Sentry.withSentryRouting(Route);
const loadingIndicator = ;
function changeAppBackground(currentTheme: any) {
if (
- window.location.pathname === "/applications" ||
+ trimTrailingSlash(window.location.pathname) === "/applications" ||
window.location.pathname.indexOf("/settings/") !== -1
) {
document.body.style.backgroundColor =
diff --git a/app/client/src/actions/applicationActions.ts b/app/client/src/actions/applicationActions.ts
index 8afecb4024..9bfdd46847 100644
--- a/app/client/src/actions/applicationActions.ts
+++ b/app/client/src/actions/applicationActions.ts
@@ -1,4 +1,6 @@
-import { ReduxActionTypes } from "constants/ReduxActionConstants";
+import { ReduxAction, ReduxActionTypes } from "constants/ReduxActionConstants";
+import { EditorModes } from "../components/editorComponents/CodeEditor/EditorConfig";
+import { APP_MODE } from "../reducers/entityReducers/appReducer";
import { UpdateApplicationPayload } from "api/ApplicationApi";
export const setDefaultApplicationPageSuccess = (
@@ -20,6 +22,24 @@ export const fetchApplications = () => {
};
};
+export interface FetchApplicationPayload {
+ applicationId: string;
+ mode: APP_MODE;
+}
+
+export const fetchApplication = (
+ applicationId: string,
+ mode: APP_MODE,
+): ReduxAction => {
+ return {
+ type: ReduxActionTypes.FETCH_APPLICATION_INIT,
+ payload: {
+ applicationId,
+ mode,
+ },
+ };
+};
+
export const updateApplication = (
id: string,
data: UpdateApplicationPayload,
@@ -33,15 +53,6 @@ export const updateApplication = (
};
};
-export const fetchApplication = (applicationId: string) => {
- return {
- type: ReduxActionTypes.FETCH_APPLICATION_INIT,
- payload: {
- applicationId,
- },
- };
-};
-
export const publishApplication = (applicationId: string) => {
return {
type: ReduxActionTypes.PUBLISH_APPLICATION_INIT,
diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx
index 465be95758..f240ce802f 100644
--- a/app/client/src/actions/pageActions.tsx
+++ b/app/client/src/actions/pageActions.tsx
@@ -2,23 +2,29 @@ import { FetchPageRequest, SavePageResponse } from "api/PageApi";
import { WidgetOperation, WidgetProps } from "widgets/BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import {
- ReduxActionTypes,
ReduxAction,
+ ReduxActionTypes,
UpdateCanvasPayload,
- FetchPageListPayload,
} from "constants/ReduxActionConstants";
import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
import { ContainerWidgetProps } from "widgets/ContainerWidget";
import AnalyticsUtil from "utils/AnalyticsUtil";
import { APP_MODE, UrlDataState } from "reducers/entityReducers/appReducer";
+export interface FetchPageListPayload {
+ applicationId: string;
+ mode: APP_MODE;
+}
+
export const fetchPageList = (
applicationId: string,
+ mode: APP_MODE,
): ReduxAction => {
return {
type: ReduxActionTypes.FETCH_PAGE_LIST_INIT,
payload: {
applicationId,
+ mode,
},
};
};
diff --git a/app/client/src/api/ActionAPI.tsx b/app/client/src/api/ActionAPI.tsx
index 085eb768a7..5c353cc8c5 100644
--- a/app/client/src/api/ActionAPI.tsx
+++ b/app/client/src/api/ActionAPI.tsx
@@ -44,13 +44,10 @@ export interface ActionCreateUpdateResponse extends ApiResponse {
export type PaginationField = "PREV" | "NEXT";
export interface ExecuteActionRequest extends APIRequest {
- action: Pick | Omit;
+ actionId: string;
params?: Property[];
paginationField?: PaginationField;
-}
-
-export interface ExecuteQueryRequest extends APIRequest {
- action: Pick | Omit;
+ viewMode: boolean;
}
export interface ExecuteActionResponse extends ApiResponse {
diff --git a/app/client/src/api/ApplicationApi.tsx b/app/client/src/api/ApplicationApi.tsx
index 82d8486590..2c8ccc69c4 100644
--- a/app/client/src/api/ApplicationApi.tsx
+++ b/app/client/src/api/ApplicationApi.tsx
@@ -129,6 +129,12 @@ class ApplicationApi extends Api {
return Api.get(ApplicationApi.baseURL + applicationId);
}
+ static fetchApplicationForViewMode(
+ applicationId: string,
+ ): AxiosPromise {
+ return Api.get(ApplicationApi.baseURL + `view/${applicationId}`);
+ }
+
static createApplication(
request: CreateApplicationRequest,
): AxiosPromise {
diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx
index 51f651b92e..c0e05681de 100644
--- a/app/client/src/api/PageApi.tsx
+++ b/app/client/src/api/PageApi.tsx
@@ -161,6 +161,12 @@ class PageApi extends Api {
return Api.get(PageApi.url + "/application/" + applicationId);
}
+ static fetchPageListViewMode(
+ applicationId: string,
+ ): AxiosPromise {
+ return Api.get(PageApi.url + "/view/application/" + applicationId);
+ }
+
static deletePage(request: DeletePageRequest): AxiosPromise {
return Api.delete(PageApi.url + "/" + request.id);
}
diff --git a/app/client/src/assets/icons/ads/bag.svg b/app/client/src/assets/icons/ads/bag.svg
index 04096a467d..8ce3bef7ce 100644
--- a/app/client/src/assets/icons/ads/bag.svg
+++ b/app/client/src/assets/icons/ads/bag.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/billing.svg b/app/client/src/assets/icons/ads/billing.svg
index daf4b246e5..99d809fa80 100644
--- a/app/client/src/assets/icons/ads/billing.svg
+++ b/app/client/src/assets/icons/ads/billing.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/book.svg b/app/client/src/assets/icons/ads/book.svg
index f016135fcd..51821b49d1 100644
--- a/app/client/src/assets/icons/ads/book.svg
+++ b/app/client/src/assets/icons/ads/book.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/calender.svg b/app/client/src/assets/icons/ads/calender.svg
index 8be12ddf06..9177c399f4 100644
--- a/app/client/src/assets/icons/ads/calender.svg
+++ b/app/client/src/assets/icons/ads/calender.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/camera.svg b/app/client/src/assets/icons/ads/camera.svg
index d1b23590c0..15c623c91f 100644
--- a/app/client/src/assets/icons/ads/camera.svg
+++ b/app/client/src/assets/icons/ads/camera.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/chat.svg b/app/client/src/assets/icons/ads/chat.svg
index 6fbbcfc754..13920a93e3 100644
--- a/app/client/src/assets/icons/ads/chat.svg
+++ b/app/client/src/assets/icons/ads/chat.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/close.svg b/app/client/src/assets/icons/ads/close.svg
index afaca4c528..0575beb7f9 100644
--- a/app/client/src/assets/icons/ads/close.svg
+++ b/app/client/src/assets/icons/ads/close.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/context-menu.svg b/app/client/src/assets/icons/ads/context-menu.svg
index 5c50eab87d..1fda6ea2b9 100644
--- a/app/client/src/assets/icons/ads/context-menu.svg
+++ b/app/client/src/assets/icons/ads/context-menu.svg
@@ -1,14 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/create-new.svg b/app/client/src/assets/icons/ads/create-new.svg
index def6849ebf..9264739e83 100644
--- a/app/client/src/assets/icons/ads/create-new.svg
+++ b/app/client/src/assets/icons/ads/create-new.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/delete.svg b/app/client/src/assets/icons/ads/delete.svg
index a39c50e042..d1e8c04c04 100644
--- a/app/client/src/assets/icons/ads/delete.svg
+++ b/app/client/src/assets/icons/ads/delete.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/down_arrow.svg b/app/client/src/assets/icons/ads/down_arrow.svg
index bf868b04ee..098793c09e 100644
--- a/app/client/src/assets/icons/ads/down_arrow.svg
+++ b/app/client/src/assets/icons/ads/down_arrow.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/duplicate.svg b/app/client/src/assets/icons/ads/duplicate.svg
index 0c31bfc467..0488d31d56 100644
--- a/app/client/src/assets/icons/ads/duplicate.svg
+++ b/app/client/src/assets/icons/ads/duplicate.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/edit.svg b/app/client/src/assets/icons/ads/edit.svg
index 93eaaa6946..5956addc8e 100644
--- a/app/client/src/assets/icons/ads/edit.svg
+++ b/app/client/src/assets/icons/ads/edit.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/error.svg b/app/client/src/assets/icons/ads/error.svg
index 43f866b350..b55ff30df6 100644
--- a/app/client/src/assets/icons/ads/error.svg
+++ b/app/client/src/assets/icons/ads/error.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/file.svg b/app/client/src/assets/icons/ads/file.svg
index 4e83e5a8ae..be191cc8d3 100644
--- a/app/client/src/assets/icons/ads/file.svg
+++ b/app/client/src/assets/icons/ads/file.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/flight.svg b/app/client/src/assets/icons/ads/flight.svg
index 0a6daa90ab..9374e31d0d 100644
--- a/app/client/src/assets/icons/ads/flight.svg
+++ b/app/client/src/assets/icons/ads/flight.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/frame.svg b/app/client/src/assets/icons/ads/frame.svg
index 3bd9d4a502..372560ab88 100644
--- a/app/client/src/assets/icons/ads/frame.svg
+++ b/app/client/src/assets/icons/ads/frame.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/general.svg b/app/client/src/assets/icons/ads/general.svg
index 6204dd6c96..f99736c21e 100644
--- a/app/client/src/assets/icons/ads/general.svg
+++ b/app/client/src/assets/icons/ads/general.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/globe.svg b/app/client/src/assets/icons/ads/globe.svg
index 228290a5d6..2ca63fec36 100644
--- a/app/client/src/assets/icons/ads/globe.svg
+++ b/app/client/src/assets/icons/ads/globe.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/heart.svg b/app/client/src/assets/icons/ads/heart.svg
index 372367768d..1587bfbb99 100644
--- a/app/client/src/assets/icons/ads/heart.svg
+++ b/app/client/src/assets/icons/ads/heart.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/invite-users.svg b/app/client/src/assets/icons/ads/invite-users.svg
index 4b0b6cd9a0..4236df2b7f 100644
--- a/app/client/src/assets/icons/ads/invite-users.svg
+++ b/app/client/src/assets/icons/ads/invite-users.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/launch.svg b/app/client/src/assets/icons/ads/launch.svg
index 83d1bd28fb..75b837aad9 100644
--- a/app/client/src/assets/icons/ads/launch.svg
+++ b/app/client/src/assets/icons/ads/launch.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/logout.svg b/app/client/src/assets/icons/ads/logout.svg
index f301b2b502..ca6ba7a170 100644
--- a/app/client/src/assets/icons/ads/logout.svg
+++ b/app/client/src/assets/icons/ads/logout.svg
@@ -1,15 +1 @@
-
-
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/manage.svg b/app/client/src/assets/icons/ads/manage.svg
index 27ba5fc70a..6e50631a1a 100644
--- a/app/client/src/assets/icons/ads/manage.svg
+++ b/app/client/src/assets/icons/ads/manage.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/product.svg b/app/client/src/assets/icons/ads/product.svg
index 9237160df7..02cf6f70df 100644
--- a/app/client/src/assets/icons/ads/product.svg
+++ b/app/client/src/assets/icons/ads/product.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/search.svg b/app/client/src/assets/icons/ads/search.svg
index e3e23f0e53..fd0abc79ae 100644
--- a/app/client/src/assets/icons/ads/search.svg
+++ b/app/client/src/assets/icons/ads/search.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/share.svg b/app/client/src/assets/icons/ads/share.svg
index 8db07e7a08..35fd9ca343 100644
--- a/app/client/src/assets/icons/ads/share.svg
+++ b/app/client/src/assets/icons/ads/share.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/shopper.svg b/app/client/src/assets/icons/ads/shopper.svg
index e8deb2e930..1a7b7eea3b 100644
--- a/app/client/src/assets/icons/ads/shopper.svg
+++ b/app/client/src/assets/icons/ads/shopper.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/success.svg b/app/client/src/assets/icons/ads/success.svg
index c5c3d40e41..db032c423d 100644
--- a/app/client/src/assets/icons/ads/success.svg
+++ b/app/client/src/assets/icons/ads/success.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/upper_arrow.svg b/app/client/src/assets/icons/ads/upper_arrow.svg
index 022072bf4a..15e203070a 100644
--- a/app/client/src/assets/icons/ads/upper_arrow.svg
+++ b/app/client/src/assets/icons/ads/upper_arrow.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/user.svg b/app/client/src/assets/icons/ads/user.svg
index e9e4b45e3d..d01937d7f2 100644
--- a/app/client/src/assets/icons/ads/user.svg
+++ b/app/client/src/assets/icons/ads/user.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/view-all.svg b/app/client/src/assets/icons/ads/view-all.svg
index 0689c29ced..f2edf62f0d 100644
--- a/app/client/src/assets/icons/ads/view-all.svg
+++ b/app/client/src/assets/icons/ads/view-all.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/ads/workspace.svg b/app/client/src/assets/icons/ads/workspace.svg
index 0c314d51fb..76b6cccd67 100644
--- a/app/client/src/assets/icons/ads/workspace.svg
+++ b/app/client/src/assets/icons/ads/workspace.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/alert/error.svg b/app/client/src/assets/icons/alert/error.svg
index addd38233f..ff3581b77b 100644
--- a/app/client/src/assets/icons/alert/error.svg
+++ b/app/client/src/assets/icons/alert/error.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/alert/info.svg b/app/client/src/assets/icons/alert/info.svg
index 145547a06f..3a608999b3 100644
--- a/app/client/src/assets/icons/alert/info.svg
+++ b/app/client/src/assets/icons/alert/info.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/alert/success.svg b/app/client/src/assets/icons/alert/success.svg
index c3221e7b06..3df2b9b839 100644
--- a/app/client/src/assets/icons/alert/success.svg
+++ b/app/client/src/assets/icons/alert/success.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/alert/warning.svg b/app/client/src/assets/icons/alert/warning.svg
index 6887ec5239..8ef6d43960 100644
--- a/app/client/src/assets/icons/alert/warning.svg
+++ b/app/client/src/assets/icons/alert/warning.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/address.svg b/app/client/src/assets/icons/control/address.svg
index 21acef28d8..cb38ae84af 100644
--- a/app/client/src/assets/icons/control/address.svg
+++ b/app/client/src/assets/icons/control/address.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/bold.svg b/app/client/src/assets/icons/control/bold.svg
index f3e136da0f..6a5ea86324 100644
--- a/app/client/src/assets/icons/control/bold.svg
+++ b/app/client/src/assets/icons/control/bold.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/center-align.svg b/app/client/src/assets/icons/control/center-align.svg
index 34e6f1a462..5071e005fc 100644
--- a/app/client/src/assets/icons/control/center-align.svg
+++ b/app/client/src/assets/icons/control/center-align.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/chevron-down.svg b/app/client/src/assets/icons/control/chevron-down.svg
index 783082577d..612b83e1e0 100644
--- a/app/client/src/assets/icons/control/chevron-down.svg
+++ b/app/client/src/assets/icons/control/chevron-down.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/close.svg b/app/client/src/assets/icons/control/close.svg
index aaeccc056d..c36a21cd8f 100644
--- a/app/client/src/assets/icons/control/close.svg
+++ b/app/client/src/assets/icons/control/close.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/collapse.svg b/app/client/src/assets/icons/control/collapse.svg
index fc7b106736..3eb84e3cee 100644
--- a/app/client/src/assets/icons/control/collapse.svg
+++ b/app/client/src/assets/icons/control/collapse.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/columns-visibility.svg b/app/client/src/assets/icons/control/columns-visibility.svg
index a44a40d859..78c503e371 100755
--- a/app/client/src/assets/icons/control/columns-visibility.svg
+++ b/app/client/src/assets/icons/control/columns-visibility.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/compact.svg b/app/client/src/assets/icons/control/compact.svg
index 8cbefd7126..82a827774e 100755
--- a/app/client/src/assets/icons/control/compact.svg
+++ b/app/client/src/assets/icons/control/compact.svg
@@ -1,9 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/copy.svg b/app/client/src/assets/icons/control/copy.svg
index e9536f2cda..4af7dfe517 100644
--- a/app/client/src/assets/icons/control/copy.svg
+++ b/app/client/src/assets/icons/control/copy.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/currency.svg b/app/client/src/assets/icons/control/currency.svg
index 2115953d27..9a6b2a0402 100644
--- a/app/client/src/assets/icons/control/currency.svg
+++ b/app/client/src/assets/icons/control/currency.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/datepicker.svg b/app/client/src/assets/icons/control/datepicker.svg
index 959f2763c8..4bfed6bf77 100644
--- a/app/client/src/assets/icons/control/datepicker.svg
+++ b/app/client/src/assets/icons/control/datepicker.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/decimal.svg b/app/client/src/assets/icons/control/decimal.svg
index a6adb8fcb5..2d12715170 100644
--- a/app/client/src/assets/icons/control/decimal.svg
+++ b/app/client/src/assets/icons/control/decimal.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/decrease.svg b/app/client/src/assets/icons/control/decrease.svg
index f8ffdccb6e..c48db3214e 100644
--- a/app/client/src/assets/icons/control/decrease.svg
+++ b/app/client/src/assets/icons/control/decrease.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/delete.svg b/app/client/src/assets/icons/control/delete.svg
index 273eb462b8..d3783c6540 100644
--- a/app/client/src/assets/icons/control/delete.svg
+++ b/app/client/src/assets/icons/control/delete.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/download-table.svg b/app/client/src/assets/icons/control/download-table.svg
index cea728e494..129ee6b5ad 100755
--- a/app/client/src/assets/icons/control/download-table.svg
+++ b/app/client/src/assets/icons/control/download-table.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/drag.svg b/app/client/src/assets/icons/control/drag.svg
index a432baa4a2..92df55d4e5 100644
--- a/app/client/src/assets/icons/control/drag.svg
+++ b/app/client/src/assets/icons/control/drag.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/draggable.svg b/app/client/src/assets/icons/control/draggable.svg
index 4be5a7b6d6..b7e2354e33 100644
--- a/app/client/src/assets/icons/control/draggable.svg
+++ b/app/client/src/assets/icons/control/draggable.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/edit-white.svg b/app/client/src/assets/icons/control/edit-white.svg
index 12b10c0305..234ebcbf9a 100644
--- a/app/client/src/assets/icons/control/edit-white.svg
+++ b/app/client/src/assets/icons/control/edit-white.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/edit.svg b/app/client/src/assets/icons/control/edit.svg
index f2ec080903..e70ce4c6d1 100644
--- a/app/client/src/assets/icons/control/edit.svg
+++ b/app/client/src/assets/icons/control/edit.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/email.svg b/app/client/src/assets/icons/control/email.svg
index 16d7748e2e..59dad51c38 100644
--- a/app/client/src/assets/icons/control/email.svg
+++ b/app/client/src/assets/icons/control/email.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/filter-icon.svg b/app/client/src/assets/icons/control/filter-icon.svg
index 0e1b16406a..1723d3efe8 100755
--- a/app/client/src/assets/icons/control/filter-icon.svg
+++ b/app/client/src/assets/icons/control/filter-icon.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/help.svg b/app/client/src/assets/icons/control/help.svg
index b2986f1fb7..1dbe805af1 100644
--- a/app/client/src/assets/icons/control/help.svg
+++ b/app/client/src/assets/icons/control/help.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/increase.svg b/app/client/src/assets/icons/control/increase.svg
index e20986e3e8..db795e36ad 100644
--- a/app/client/src/assets/icons/control/increase.svg
+++ b/app/client/src/assets/icons/control/increase.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/info.svg b/app/client/src/assets/icons/control/info.svg
index 300bcd9a06..95aa0a81ae 100644
--- a/app/client/src/assets/icons/control/info.svg
+++ b/app/client/src/assets/icons/control/info.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/input.svg b/app/client/src/assets/icons/control/input.svg
index aeac1584b3..ad382f9790 100644
--- a/app/client/src/assets/icons/control/input.svg
+++ b/app/client/src/assets/icons/control/input.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/integer.svg b/app/client/src/assets/icons/control/integer.svg
index cd3e6a56c7..25969f3b1a 100644
--- a/app/client/src/assets/icons/control/integer.svg
+++ b/app/client/src/assets/icons/control/integer.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/italics.svg b/app/client/src/assets/icons/control/italics.svg
index 7ae3bbba66..51c317d687 100644
--- a/app/client/src/assets/icons/control/italics.svg
+++ b/app/client/src/assets/icons/control/italics.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/js-toggle.svg b/app/client/src/assets/icons/control/js-toggle.svg
index 616e8556f6..2698942924 100644
--- a/app/client/src/assets/icons/control/js-toggle.svg
+++ b/app/client/src/assets/icons/control/js-toggle.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/launch.svg b/app/client/src/assets/icons/control/launch.svg
index 09e2d1ce7a..74e7c04904 100644
--- a/app/client/src/assets/icons/control/launch.svg
+++ b/app/client/src/assets/icons/control/launch.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/left-align.svg b/app/client/src/assets/icons/control/left-align.svg
index 94eb13e628..d5c3b826c5 100644
--- a/app/client/src/assets/icons/control/left-align.svg
+++ b/app/client/src/assets/icons/control/left-align.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/lightning.svg b/app/client/src/assets/icons/control/lightning.svg
index 2c56892354..e611c04972 100644
--- a/app/client/src/assets/icons/control/lightning.svg
+++ b/app/client/src/assets/icons/control/lightning.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/more-vertical.svg b/app/client/src/assets/icons/control/more-vertical.svg
index e9a7600622..b8b10537a1 100755
--- a/app/client/src/assets/icons/control/more-vertical.svg
+++ b/app/client/src/assets/icons/control/more-vertical.svg
@@ -1,8 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/move.svg b/app/client/src/assets/icons/control/move.svg
index 3cd36f1c26..9dce6c62a7 100644
--- a/app/client/src/assets/icons/control/move.svg
+++ b/app/client/src/assets/icons/control/move.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/multiline.svg b/app/client/src/assets/icons/control/multiline.svg
index 220bfad216..ba7bb1e4c1 100644
--- a/app/client/src/assets/icons/control/multiline.svg
+++ b/app/client/src/assets/icons/control/multiline.svg
@@ -1,8 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/password.svg b/app/client/src/assets/icons/control/password.svg
index ad542c6f95..958ea5f324 100644
--- a/app/client/src/assets/icons/control/password.svg
+++ b/app/client/src/assets/icons/control/password.svg
@@ -1,9 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/phone.svg b/app/client/src/assets/icons/control/phone.svg
index 33fc877272..8d43cad519 100644
--- a/app/client/src/assets/icons/control/phone.svg
+++ b/app/client/src/assets/icons/control/phone.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/pick-location-initial.svg b/app/client/src/assets/icons/control/pick-location-initial.svg
index 2572dd77b9..adc4d22906 100644
--- a/app/client/src/assets/icons/control/pick-location-initial.svg
+++ b/app/client/src/assets/icons/control/pick-location-initial.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/pick-location-onclick.svg b/app/client/src/assets/icons/control/pick-location-onclick.svg
index f8fb48fbe5..24e2db51f9 100644
--- a/app/client/src/assets/icons/control/pick-location-onclick.svg
+++ b/app/client/src/assets/icons/control/pick-location-onclick.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/pick-location-selected.svg b/app/client/src/assets/icons/control/pick-location-selected.svg
index 29d9c89835..edf7da2f08 100644
--- a/app/client/src/assets/icons/control/pick-location-selected.svg
+++ b/app/client/src/assets/icons/control/pick-location-selected.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/pick-my-location.svg b/app/client/src/assets/icons/control/pick-my-location.svg
index e519a17dd3..8655546aa2 100644
--- a/app/client/src/assets/icons/control/pick-my-location.svg
+++ b/app/client/src/assets/icons/control/pick-my-location.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/play-icon.png b/app/client/src/assets/icons/control/play-icon.png
index 52ddde9e4f..48ca301f33 100644
Binary files a/app/client/src/assets/icons/control/play-icon.png and b/app/client/src/assets/icons/control/play-icon.png differ
diff --git a/app/client/src/assets/icons/control/redo.svg b/app/client/src/assets/icons/control/redo.svg
index 71bfe8be4e..77c7dae9e9 100644
--- a/app/client/src/assets/icons/control/redo.svg
+++ b/app/client/src/assets/icons/control/redo.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/remove.svg b/app/client/src/assets/icons/control/remove.svg
index b3db7ea3ce..14e58f2cc5 100755
--- a/app/client/src/assets/icons/control/remove.svg
+++ b/app/client/src/assets/icons/control/remove.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/right-align.svg b/app/client/src/assets/icons/control/right-align.svg
index 967eb8d1fb..f62b86260a 100644
--- a/app/client/src/assets/icons/control/right-align.svg
+++ b/app/client/src/assets/icons/control/right-align.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/search.svg b/app/client/src/assets/icons/control/search.svg
index 3aa4f00565..364ae959ce 100644
--- a/app/client/src/assets/icons/control/search.svg
+++ b/app/client/src/assets/icons/control/search.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/settings.svg b/app/client/src/assets/icons/control/settings.svg
index 5bc7daef54..e6a03bf534 100644
--- a/app/client/src/assets/icons/control/settings.svg
+++ b/app/client/src/assets/icons/control/settings.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/sort-icon.svg b/app/client/src/assets/icons/control/sort-icon.svg
index f1862442de..02f54b7846 100755
--- a/app/client/src/assets/icons/control/sort-icon.svg
+++ b/app/client/src/assets/icons/control/sort-icon.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/underline.svg b/app/client/src/assets/icons/control/underline.svg
index 12a393304a..8447bfc39d 100644
--- a/app/client/src/assets/icons/control/underline.svg
+++ b/app/client/src/assets/icons/control/underline.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/undo.svg b/app/client/src/assets/icons/control/undo.svg
index 2ec8e0fb7c..e7b58feae4 100644
--- a/app/client/src/assets/icons/control/undo.svg
+++ b/app/client/src/assets/icons/control/undo.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/view.svg b/app/client/src/assets/icons/control/view.svg
index 66010d6eed..90d61a745b 100644
--- a/app/client/src/assets/icons/control/view.svg
+++ b/app/client/src/assets/icons/control/view.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/zoomin.svg b/app/client/src/assets/icons/control/zoomin.svg
index baa27c369d..2af30e2b17 100644
--- a/app/client/src/assets/icons/control/zoomin.svg
+++ b/app/client/src/assets/icons/control/zoomin.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/control/zoomout.svg b/app/client/src/assets/icons/control/zoomout.svg
index aceffa4ff6..6f1fb70136 100644
--- a/app/client/src/assets/icons/control/zoomout.svg
+++ b/app/client/src/assets/icons/control/zoomout.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/form/add-new.svg b/app/client/src/assets/icons/form/add-new.svg
index 6edbd99663..2b36469eb0 100644
--- a/app/client/src/assets/icons/form/add-new.svg
+++ b/app/client/src/assets/icons/form/add-new.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/form/info-outline.svg b/app/client/src/assets/icons/form/info-outline.svg
index 0cfe7d23e0..0782dabbbe 100644
--- a/app/client/src/assets/icons/form/info-outline.svg
+++ b/app/client/src/assets/icons/form/info-outline.svg
@@ -1,13 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/form/lock.svg b/app/client/src/assets/icons/form/lock.svg
new file mode 100644
index 0000000000..eba05a3753
--- /dev/null
+++ b/app/client/src/assets/icons/form/lock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/form/trash.svg b/app/client/src/assets/icons/form/trash.svg
index 04a04629f3..6ae5e921f8 100755
--- a/app/client/src/assets/icons/form/trash.svg
+++ b/app/client/src/assets/icons/form/trash.svg
@@ -1,6 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/header/deploy.svg b/app/client/src/assets/icons/header/deploy.svg
index faa203e316..37bdd9d812 100644
--- a/app/client/src/assets/icons/header/deploy.svg
+++ b/app/client/src/assets/icons/header/deploy.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/header/feedback.svg b/app/client/src/assets/icons/header/feedback.svg
index 4eba24b0c4..bfb512b8c3 100644
--- a/app/client/src/assets/icons/header/feedback.svg
+++ b/app/client/src/assets/icons/header/feedback.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/header/save-failure.svg b/app/client/src/assets/icons/header/save-failure.svg
index d1d8ba1915..b6210197ea 100644
--- a/app/client/src/assets/icons/header/save-failure.svg
+++ b/app/client/src/assets/icons/header/save-failure.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/header/save-loading.gif b/app/client/src/assets/icons/header/save-loading.gif
index b7cfcf3cab..504e82ba8d 100644
Binary files a/app/client/src/assets/icons/header/save-loading.gif and b/app/client/src/assets/icons/header/save-loading.gif differ
diff --git a/app/client/src/assets/icons/header/save-success.svg b/app/client/src/assets/icons/header/save-success.svg
index a6b536bbe9..340e58cf32 100644
--- a/app/client/src/assets/icons/header/save-success.svg
+++ b/app/client/src/assets/icons/header/save-success.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/header/share-white.svg b/app/client/src/assets/icons/header/share-white.svg
index c967dc8d12..f90ae1bb14 100644
--- a/app/client/src/assets/icons/header/share-white.svg
+++ b/app/client/src/assets/icons/header/share-white.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/help/discord.svg b/app/client/src/assets/icons/help/discord.svg
index 4613aa9ae8..ee334bbc7e 100644
--- a/app/client/src/assets/icons/help/discord.svg
+++ b/app/client/src/assets/icons/help/discord.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/help/document.svg b/app/client/src/assets/icons/help/document.svg
index e0ba8bc5cb..bf8d13cf1e 100644
--- a/app/client/src/assets/icons/help/document.svg
+++ b/app/client/src/assets/icons/help/document.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/help/github-icon.svg b/app/client/src/assets/icons/help/github-icon.svg
index 3f18b45241..7126204ff8 100644
--- a/app/client/src/assets/icons/help/github-icon.svg
+++ b/app/client/src/assets/icons/help/github-icon.svg
@@ -1,27 +1 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/help/help.svg b/app/client/src/assets/icons/help/help.svg
index e041a79ee3..46d0b764c4 100644
--- a/app/client/src/assets/icons/help/help.svg
+++ b/app/client/src/assets/icons/help/help.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/help/openlink.svg b/app/client/src/assets/icons/help/openlink.svg
index 972fe06226..4b64b21ed3 100644
--- a/app/client/src/assets/icons/help/openlink.svg
+++ b/app/client/src/assets/icons/help/openlink.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/api-colored.svg b/app/client/src/assets/icons/menu/api-colored.svg
index 6d202ff595..939235b6b1 100644
--- a/app/client/src/assets/icons/menu/api-colored.svg
+++ b/app/client/src/assets/icons/menu/api-colored.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/api.svg b/app/client/src/assets/icons/menu/api.svg
index 78dcf2a32f..a81046b50d 100644
--- a/app/client/src/assets/icons/menu/api.svg
+++ b/app/client/src/assets/icons/menu/api.svg
@@ -1,6 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/data-sources.svg b/app/client/src/assets/icons/menu/data-sources.svg
index ce5d38c669..63cc842f80 100644
--- a/app/client/src/assets/icons/menu/data-sources.svg
+++ b/app/client/src/assets/icons/menu/data-sources.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/datasource-colored.svg b/app/client/src/assets/icons/menu/datasource-colored.svg
index f779edcee5..ae022d43fc 100644
--- a/app/client/src/assets/icons/menu/datasource-colored.svg
+++ b/app/client/src/assets/icons/menu/datasource-colored.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/datasource-column.svg b/app/client/src/assets/icons/menu/datasource-column.svg
index da70f69a9d..695d40a98c 100644
--- a/app/client/src/assets/icons/menu/datasource-column.svg
+++ b/app/client/src/assets/icons/menu/datasource-column.svg
@@ -1,11 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/datasource-table.svg b/app/client/src/assets/icons/menu/datasource-table.svg
index 76c3e9bf9b..a3c30a69fb 100644
--- a/app/client/src/assets/icons/menu/datasource-table.svg
+++ b/app/client/src/assets/icons/menu/datasource-table.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/explorer.svg b/app/client/src/assets/icons/menu/explorer.svg
index af233a1ee9..1284f5ad5f 100644
--- a/app/client/src/assets/icons/menu/explorer.svg
+++ b/app/client/src/assets/icons/menu/explorer.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/foreign-key.svg b/app/client/src/assets/icons/menu/foreign-key.svg
index 786add7c56..7003efae12 100644
--- a/app/client/src/assets/icons/menu/foreign-key.svg
+++ b/app/client/src/assets/icons/menu/foreign-key.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/homepage.svg b/app/client/src/assets/icons/menu/homepage.svg
index 2c34a49d48..0451341726 100644
--- a/app/client/src/assets/icons/menu/homepage.svg
+++ b/app/client/src/assets/icons/menu/homepage.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/org.svg b/app/client/src/assets/icons/menu/org.svg
index fcfd90d8e0..a644fb6d78 100644
--- a/app/client/src/assets/icons/menu/org.svg
+++ b/app/client/src/assets/icons/menu/org.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/overflow-menu.svg b/app/client/src/assets/icons/menu/overflow-menu.svg
index 1e1ffd2d40..3d9237e06c 100644
--- a/app/client/src/assets/icons/menu/overflow-menu.svg
+++ b/app/client/src/assets/icons/menu/overflow-menu.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/page.svg b/app/client/src/assets/icons/menu/page.svg
index dc184d19ce..5ad6c9eab1 100644
--- a/app/client/src/assets/icons/menu/page.svg
+++ b/app/client/src/assets/icons/menu/page.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/pages.svg b/app/client/src/assets/icons/menu/pages.svg
index fcafce2c0b..95114f63d8 100644
--- a/app/client/src/assets/icons/menu/pages.svg
+++ b/app/client/src/assets/icons/menu/pages.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/primary-key.svg b/app/client/src/assets/icons/menu/primary-key.svg
index 12311634e5..2ff17003e1 100644
--- a/app/client/src/assets/icons/menu/primary-key.svg
+++ b/app/client/src/assets/icons/menu/primary-key.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/queries.svg b/app/client/src/assets/icons/menu/queries.svg
index 44abd92bf2..e8d26e3a53 100644
--- a/app/client/src/assets/icons/menu/queries.svg
+++ b/app/client/src/assets/icons/menu/queries.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/storage.svg b/app/client/src/assets/icons/menu/storage.svg
index a856115925..315b78ac5c 100644
--- a/app/client/src/assets/icons/menu/storage.svg
+++ b/app/client/src/assets/icons/menu/storage.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/widgets-colored.svg b/app/client/src/assets/icons/menu/widgets-colored.svg
index f28f50fc3e..181f517469 100644
--- a/app/client/src/assets/icons/menu/widgets-colored.svg
+++ b/app/client/src/assets/icons/menu/widgets-colored.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/menu/widgets.svg b/app/client/src/assets/icons/menu/widgets.svg
index a48d556b21..d33c24c427 100644
--- a/app/client/src/assets/icons/menu/widgets.svg
+++ b/app/client/src/assets/icons/menu/widgets.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/alert.svg b/app/client/src/assets/icons/widget/alert.svg
index 74a2019404..71eeb2297a 100644
--- a/app/client/src/assets/icons/widget/alert.svg
+++ b/app/client/src/assets/icons/widget/alert.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/button.svg b/app/client/src/assets/icons/widget/button.svg
index 24c4944870..8acae73d9a 100644
--- a/app/client/src/assets/icons/widget/button.svg
+++ b/app/client/src/assets/icons/widget/button.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/chart.svg b/app/client/src/assets/icons/widget/chart.svg
index 98e609cb6c..5479998b18 100644
--- a/app/client/src/assets/icons/widget/chart.svg
+++ b/app/client/src/assets/icons/widget/chart.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/checkbox.svg b/app/client/src/assets/icons/widget/checkbox.svg
index 0947945076..7734916af5 100644
--- a/app/client/src/assets/icons/widget/checkbox.svg
+++ b/app/client/src/assets/icons/widget/checkbox.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/collapse.svg b/app/client/src/assets/icons/widget/collapse.svg
index 772bc19548..8cbcb11329 100644
--- a/app/client/src/assets/icons/widget/collapse.svg
+++ b/app/client/src/assets/icons/widget/collapse.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/container.svg b/app/client/src/assets/icons/widget/container.svg
index ed7bd00a1f..e97d99915a 100644
--- a/app/client/src/assets/icons/widget/container.svg
+++ b/app/client/src/assets/icons/widget/container.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/datepicker.svg b/app/client/src/assets/icons/widget/datepicker.svg
index 80c0c8bd7b..76980a5b33 100644
--- a/app/client/src/assets/icons/widget/datepicker.svg
+++ b/app/client/src/assets/icons/widget/datepicker.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/dropdown.svg b/app/client/src/assets/icons/widget/dropdown.svg
index 6caa5e0bf6..5e689f59c0 100644
--- a/app/client/src/assets/icons/widget/dropdown.svg
+++ b/app/client/src/assets/icons/widget/dropdown.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/filepicker.svg b/app/client/src/assets/icons/widget/filepicker.svg
index 3339c43747..88b52ea19c 100644
--- a/app/client/src/assets/icons/widget/filepicker.svg
+++ b/app/client/src/assets/icons/widget/filepicker.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/form.svg b/app/client/src/assets/icons/widget/form.svg
index 17484c70a3..f0153a9352 100644
--- a/app/client/src/assets/icons/widget/form.svg
+++ b/app/client/src/assets/icons/widget/form.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/image.svg b/app/client/src/assets/icons/widget/image.svg
index e1bb405a2d..c1eb966be5 100644
--- a/app/client/src/assets/icons/widget/image.svg
+++ b/app/client/src/assets/icons/widget/image.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/input.svg b/app/client/src/assets/icons/widget/input.svg
index 8dda85dd5b..8b24e7d3de 100644
--- a/app/client/src/assets/icons/widget/input.svg
+++ b/app/client/src/assets/icons/widget/input.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/location-picker.svg b/app/client/src/assets/icons/widget/location-picker.svg
index 254038ecd5..68150b62e1 100644
--- a/app/client/src/assets/icons/widget/location-picker.svg
+++ b/app/client/src/assets/icons/widget/location-picker.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/map.svg b/app/client/src/assets/icons/widget/map.svg
index 61c7b73472..7b57ee9c68 100755
--- a/app/client/src/assets/icons/widget/map.svg
+++ b/app/client/src/assets/icons/widget/map.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/modal.svg b/app/client/src/assets/icons/widget/modal.svg
index 1f1b1ad84b..edede7d2d6 100644
--- a/app/client/src/assets/icons/widget/modal.svg
+++ b/app/client/src/assets/icons/widget/modal.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/plus.svg b/app/client/src/assets/icons/widget/plus.svg
index fc1aa5b1f1..ca280afea0 100644
--- a/app/client/src/assets/icons/widget/plus.svg
+++ b/app/client/src/assets/icons/widget/plus.svg
@@ -1,4 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/radio.svg b/app/client/src/assets/icons/widget/radio.svg
index c609d61986..a2e3539fae 100644
--- a/app/client/src/assets/icons/widget/radio.svg
+++ b/app/client/src/assets/icons/widget/radio.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/rich-text.svg b/app/client/src/assets/icons/widget/rich-text.svg
index 99149884a5..437c2a12c4 100644
--- a/app/client/src/assets/icons/widget/rich-text.svg
+++ b/app/client/src/assets/icons/widget/rich-text.svg
@@ -1,8 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/slash.svg b/app/client/src/assets/icons/widget/slash.svg
index cd450db315..e32936f698 100644
--- a/app/client/src/assets/icons/widget/slash.svg
+++ b/app/client/src/assets/icons/widget/slash.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/switch.svg b/app/client/src/assets/icons/widget/switch.svg
index ba199d4f77..2336cc09da 100644
--- a/app/client/src/assets/icons/widget/switch.svg
+++ b/app/client/src/assets/icons/widget/switch.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/table.svg b/app/client/src/assets/icons/widget/table.svg
index 9d0ca98a83..743c7810f4 100644
--- a/app/client/src/assets/icons/widget/table.svg
+++ b/app/client/src/assets/icons/widget/table.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/tabs.svg b/app/client/src/assets/icons/widget/tabs.svg
index 0a155f14cd..9e9e748921 100644
--- a/app/client/src/assets/icons/widget/tabs.svg
+++ b/app/client/src/assets/icons/widget/tabs.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/text.svg b/app/client/src/assets/icons/widget/text.svg
index f4a474a5d9..14d8101ef8 100644
--- a/app/client/src/assets/icons/widget/text.svg
+++ b/app/client/src/assets/icons/widget/text.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/icons/widget/video.svg b/app/client/src/assets/icons/widget/video.svg
index 11426cec91..62b2bbc194 100644
--- a/app/client/src/assets/icons/widget/video.svg
+++ b/app/client/src/assets/icons/widget/video.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/404-image.png b/app/client/src/assets/images/404-image.png
index cba759370c..c962f6da35 100644
Binary files a/app/client/src/assets/images/404-image.png and b/app/client/src/assets/images/404-image.png differ
diff --git a/app/client/src/assets/images/API.svg b/app/client/src/assets/images/API.svg
index 9eca1b78bb..9c212ea28d 100644
--- a/app/client/src/assets/images/API.svg
+++ b/app/client/src/assets/images/API.svg
@@ -1,19 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/Curl-logo.svg b/app/client/src/assets/images/Curl-logo.svg
index e574f5f631..08f86ba19f 100644
--- a/app/client/src/assets/images/Curl-logo.svg
+++ b/app/client/src/assets/images/Curl-logo.svg
@@ -1,10 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/Curl.png b/app/client/src/assets/images/Curl.png
index 474feeef84..85f92e369a 100644
Binary files a/app/client/src/assets/images/Curl.png and b/app/client/src/assets/images/Curl.png differ
diff --git a/app/client/src/assets/images/EditPen.svg b/app/client/src/assets/images/EditPen.svg
index 0d6d1dba80..1742e7c90a 100644
--- a/app/client/src/assets/images/EditPen.svg
+++ b/app/client/src/assets/images/EditPen.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/Github.png b/app/client/src/assets/images/Github.png
index ea6ff545a2..dcf611c9c2 100644
Binary files a/app/client/src/assets/images/Github.png and b/app/client/src/assets/images/Github.png differ
diff --git a/app/client/src/assets/images/Google.png b/app/client/src/assets/images/Google.png
index f90e063212..fa90afe9fe 100644
Binary files a/app/client/src/assets/images/Google.png and b/app/client/src/assets/images/Google.png differ
diff --git a/app/client/src/assets/images/NoSearchResult.svg b/app/client/src/assets/images/NoSearchResult.svg
index d5a60d0c60..b733d943d9 100644
--- a/app/client/src/assets/images/NoSearchResult.svg
+++ b/app/client/src/assets/images/NoSearchResult.svg
@@ -1,39 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/Postman.png b/app/client/src/assets/images/Postman.png
index cfd823454d..c1ebd3cc3b 100644
Binary files a/app/client/src/assets/images/Postman.png and b/app/client/src/assets/images/Postman.png differ
diff --git a/app/client/src/assets/images/appsmith-datasource.svg b/app/client/src/assets/images/appsmith-datasource.svg
new file mode 100644
index 0000000000..21f7ae5258
--- /dev/null
+++ b/app/client/src/assets/images/appsmith-datasource.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/appsmith_logo.png b/app/client/src/assets/images/appsmith_logo.png
index 41dec42f1c..a6a492bbe1 100644
Binary files a/app/client/src/assets/images/appsmith_logo.png and b/app/client/src/assets/images/appsmith_logo.png differ
diff --git a/app/client/src/assets/images/appsmith_logo_white.png b/app/client/src/assets/images/appsmith_logo_white.png
index 3b01566236..872e5b2ce0 100644
Binary files a/app/client/src/assets/images/appsmith_logo_white.png and b/app/client/src/assets/images/appsmith_logo_white.png differ
diff --git a/app/client/src/assets/images/email-not-configured.svg b/app/client/src/assets/images/email-not-configured.svg
index 2ddfaaec3d..e93f6a8376 100644
--- a/app/client/src/assets/images/email-not-configured.svg
+++ b/app/client/src/assets/images/email-not-configured.svg
@@ -1,78 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/logo.svg b/app/client/src/assets/images/logo.svg
index 6b60c1042f..9dfc1c058c 100755
--- a/app/client/src/assets/images/logo.svg
+++ b/app/client/src/assets/images/logo.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/no_image.png b/app/client/src/assets/images/no_image.png
index cb274965d4..f2a39de98b 100644
Binary files a/app/client/src/assets/images/no_image.png and b/app/client/src/assets/images/no_image.png differ
diff --git a/app/client/src/assets/images/placeholder-image.svg b/app/client/src/assets/images/placeholder-image.svg
index a3e57e6cd4..8c6be0447e 100644
--- a/app/client/src/assets/images/placeholder-image.svg
+++ b/app/client/src/assets/images/placeholder-image.svg
@@ -1,3 +1 @@
-
+
\ No newline at end of file
diff --git a/app/client/src/assets/images/query-image-outline.png b/app/client/src/assets/images/query-image-outline.png
new file mode 100644
index 0000000000..5fa3fc7475
Binary files /dev/null and b/app/client/src/assets/images/query-image-outline.png differ
diff --git a/app/client/src/assets/images/secure.svg b/app/client/src/assets/images/secure.svg
new file mode 100644
index 0000000000..1567f28f1c
--- /dev/null
+++ b/app/client/src/assets/images/secure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/client/src/components/ads/ColorSelector.tsx b/app/client/src/components/ads/ColorSelector.tsx
index ff01cfbac2..3fae16e43e 100644
--- a/app/client/src/components/ads/ColorSelector.tsx
+++ b/app/client/src/components/ads/ColorSelector.tsx
@@ -76,9 +76,14 @@ const ColorSelector = (props: ColorSelectorProps) => {
selected={selected}
color={hex}
onClick={() => {
- setSelected(hex);
- props.onSelect && props.onSelect(hex);
+ if (selected !== hex) {
+ setSelected(hex);
+ props.onSelect && props.onSelect(hex);
+ }
}}
+ className={
+ selected === hex ? "t--color-selected" : "t--color-not-selected"
+ }
/>
);
})}
diff --git a/app/client/src/components/ads/EditableText.tsx b/app/client/src/components/ads/EditableText.tsx
index 4377f0b0fb..75aa557ffd 100644
--- a/app/client/src/components/ads/EditableText.tsx
+++ b/app/client/src/components/ads/EditableText.tsx
@@ -21,28 +21,28 @@ export enum SavingState {
ERROR = "ERROR",
}
-type EditableTextProps = CommonComponentProps & {
+export type EditableTextProps = CommonComponentProps & {
defaultValue: string;
- onTextChanged: (value: string) => void;
- placeholder: string;
+ placeholder?: string;
+ editInteractionKind: EditInteractionKind;
+ savingState: SavingState;
+ onBlur: (value: string) => void;
+ onTextChanged?: (value: string) => void;
className?: string;
valueTransform?: (value: string) => string;
isEditingDefault?: boolean;
forceDefault?: boolean;
updating?: boolean;
isInvalid?: (value: string) => string | boolean;
- editInteractionKind: EditInteractionKind;
hideEditIcon?: boolean;
fill?: boolean;
- savingState: SavingState;
- onBlur: (value: string) => void;
};
const EditableTextWrapper = styled.div<{
fill?: boolean;
}>`
width: ${props => (!props.fill ? "234px" : "100%")};
- .${Classes.TEXT} {
+ .error-message {
margin-left: ${props => props.theme.spaces[5]}px;
color: ${props => props.theme.colors.danger.main};
}
@@ -70,10 +70,6 @@ const TextContainer = styled.div<{
}>`
display: flex;
align-items: center;
- ${props =>
- props.isEditing && props.isInvalid
- ? `margin-bottom: ${props.theme.spaces[2]}px`
- : null};
.bp3-editable-text.bp3-editable-text-editing::before,
.bp3-editable-text.bp3-disabled::before {
display: none;
@@ -143,7 +139,6 @@ export const EditableText = (props: EditableTextProps) => {
const [savingState, setSavingState] = useState(
SavingState.NOT_STARTED,
);
- const valueRef = React.useRef(defaultValue);
useEffect(() => {
setSavingState(props.savingState);
@@ -178,14 +173,14 @@ export const EditableText = (props: EditableTextProps) => {
const onConfirm = useCallback(
(_value: string) => {
- if (savingState === SavingState.ERROR || isInvalid) {
+ if (savingState === SavingState.ERROR || isInvalid || _value === "") {
setValue(lastValidValue);
onBlur(lastValidValue);
setSavingState(SavingState.NOT_STARTED);
} else if (changeStarted) {
- onTextChanged(_value);
- onBlur(_value);
+ onTextChanged && onTextChanged(_value);
}
+ onBlur(_value);
setIsEditing(false);
setChangeStarted(false);
},
@@ -204,10 +199,9 @@ export const EditableText = (props: EditableTextProps) => {
const finalVal: string = _value;
const errorMessage = inputValidation && inputValidation(finalVal);
const error = errorMessage ? errorMessage : false;
- if (!error) {
+ if (!error && _value !== "") {
setLastValidValue(finalVal);
- valueRef.current = finalVal;
- onTextChanged(finalVal);
+ onTextChanged && onTextChanged(finalVal);
}
setValue(finalVal);
setIsInvalid(error);
@@ -258,8 +252,8 @@ export const EditableText = (props: EditableTextProps) => {
onChange={onInputchange}
onConfirm={onConfirm}
value={value}
- selectAllOnFocus
- placeholder={props.placeholder}
+ selectAllOnFocus={true}
+ placeholder={props.placeholder || defaultValue}
className={props.className}
onCancel={onConfirm}
/>
@@ -267,13 +261,15 @@ export const EditableText = (props: EditableTextProps) => {
{savingState === SavingState.STARTED ? (
- ) : (
+ ) : value ? (
- )}
+ ) : null}
{isEditing && !!isInvalid ? (
- {isInvalid}
+
+ {isInvalid}
+
) : null}
);
diff --git a/app/client/src/components/ads/EditableTextWrapper.tsx b/app/client/src/components/ads/EditableTextWrapper.tsx
new file mode 100644
index 0000000000..7e64cd6ab5
--- /dev/null
+++ b/app/client/src/components/ads/EditableTextWrapper.tsx
@@ -0,0 +1,81 @@
+import EditableText, { EditableTextProps, SavingState } from "./EditableText";
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+import { Classes } from "@blueprintjs/core";
+
+type EditableTextWrapperProps = EditableTextProps & {
+ variant: "UNDERLINE" | "ICON";
+ isNewApp: boolean;
+};
+
+const Container = styled.div<{
+ isEditing?: boolean;
+ savingState: SavingState;
+ isInvalid: boolean;
+}>`
+ &&& .${Classes.EDITABLE_TEXT}, .icon-wrapper {
+ padding: 5px 10px;
+ height: 25px;
+ text-decoration: ${props => (props.isEditing ? "unset" : "underline")};
+ background-color: ${props =>
+ (props.isInvalid && props.isEditing) ||
+ props.savingState === SavingState.ERROR
+ ? props.theme.colors.editableText.dangerBg
+ : "transparent"};
+ }
+
+ &&& .${Classes.EDITABLE_TEXT_CONTENT}, &&& .${Classes.EDITABLE_TEXT_INPUT} {
+ text-align: center;
+ color: #d4d4d4;
+ font-size: ${props => props.theme.typography.h4.fontSize}px;
+ line-height: ${props => props.theme.typography.h4.lineHeight}px;
+ letter-spacing: ${props => props.theme.typography.h4.letterSpacing}px;
+ font-weight: ${props => props.theme.typography.h4.fontWeight}px;
+ }
+
+ .error-message {
+ margin-top: 2px;
+ }
+`;
+
+export default function EditableTextWrapper(props: EditableTextWrapperProps) {
+ const [isEditing, setIsEditing] = useState(props.isNewApp);
+ const [isValid, setIsValid] = useState(false);
+
+ useEffect(() => {
+ setIsEditing(props.isNewApp);
+ }, [props.isNewApp]);
+
+ return (
+
+ {
+ setIsEditing(false);
+ props.onBlur(value);
+ }}
+ className={props.className}
+ onTextChanged={(value: string) => setIsEditing(true)}
+ isInvalid={(value: string) => {
+ setIsEditing(true);
+ if (props.isInvalid) {
+ setIsValid(Boolean(props.isInvalid(value)));
+ return props.isInvalid(value);
+ } else {
+ return false;
+ }
+ }}
+ />
+
+ );
+}
diff --git a/app/client/src/components/ads/IconSelector.tsx b/app/client/src/components/ads/IconSelector.tsx
index 0dc17980fb..70bd3ba5d2 100644
--- a/app/client/src/components/ads/IconSelector.tsx
+++ b/app/client/src/components/ads/IconSelector.tsx
@@ -73,9 +73,16 @@ const IconSelector = (props: IconSelectorProps) => {
{
- setSelected(iconName);
- props.onSelect && props.onSelect(iconName);
+ if (iconName !== selected) {
+ setSelected(iconName);
+ props.onSelect && props.onSelect(iconName);
+ }
}}
>
diff --git a/app/client/src/components/ads/TagInputComponent.tsx b/app/client/src/components/ads/TagInputComponent.tsx
index 2bfb538882..5e1db6998e 100644
--- a/app/client/src/components/ads/TagInputComponent.tsx
+++ b/app/client/src/components/ads/TagInputComponent.tsx
@@ -2,6 +2,9 @@ import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { Classes, TagInput } from "@blueprintjs/core";
import { Intent } from "constants/DefaultTheme";
+import { WrappedFieldMetaProps } from "redux-form";
+import { INVITE_USERS_VALIDATION_EMAIL_LIST } from "constants/messages";
+import { isEmail } from "utils/formhelpers";
const TagInputWrapper = styled.div<{ intent?: Intent }>`
margin-right: 8px;
@@ -48,6 +51,7 @@ type TagInputProps = {
/** Intent of the tags, which defines their color */
intent?: Intent;
hasError?: boolean;
+ customError: (values: any) => void;
};
/**
@@ -71,10 +75,25 @@ const TagInputComponent = (props: TagInputProps) => {
}
}, [_values, values]);
+ const validateEmail = (newValues: string[]) => {
+ if (newValues && newValues.length > 0) {
+ let error = "";
+ newValues.forEach((user: any) => {
+ if (!isEmail(user)) {
+ error = INVITE_USERS_VALIDATION_EMAIL_LIST;
+ }
+ });
+ props.customError(error);
+ } else {
+ props.customError("");
+ }
+ };
+
const commitValues = (newValues: string[]) => {
setValues(newValues);
props.input.onChange &&
props.input.onChange(newValues.filter(Boolean).join(","));
+ validateEmail(newValues);
};
const onTagsChange = (values: React.ReactNode[]) => {
diff --git a/app/client/src/components/ads/TextInput.tsx b/app/client/src/components/ads/TextInput.tsx
index 482f2477b7..1674a4bb02 100644
--- a/app/client/src/components/ads/TextInput.tsx
+++ b/app/client/src/components/ads/TextInput.tsx
@@ -175,7 +175,7 @@ const TextInput = forwardRef(
);
return (
-
+
{ErrorMessage}
diff --git a/app/client/src/components/designSystems/appsmith/ImageComponent.tsx b/app/client/src/components/designSystems/appsmith/ImageComponent.tsx
index b05a024cad..365475af3d 100644
--- a/app/client/src/components/designSystems/appsmith/ImageComponent.tsx
+++ b/app/client/src/components/designSystems/appsmith/ImageComponent.tsx
@@ -1,6 +1,7 @@
import * as React from "react";
import { ComponentProps } from "./BaseComponent";
import styled from "styled-components";
+import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
export interface StyledImageProps {
defaultImageUrl: string;
@@ -16,7 +17,7 @@ export const StyledImage = styled.div<
}
>`
position: relative;
- display: flex;
+ display: flex;
flex-direction: "row";
cursor: ${props =>
props.showHoverPointer && props.onClick ? "pointer" : "inherit"};
@@ -30,37 +31,133 @@ export const StyledImage = styled.div<
width: 100%;
`;
+const Wrapper = styled.div`
+ height: 100%;
+ width: 100%;
+ .react-transform-element,
+ .react-transform-component {
+ height: 100%;
+ width: 100%;
+ }
+`;
+
+enum ZoomingState {
+ MAX_ZOOMED_OUT = "MAX_ZOOMED_OUT",
+ MAX_ZOOMED_IN = "MAX_ZOOMED_IN",
+}
class ImageComponent extends React.Component<
ImageComponentProps,
{
imageError: boolean;
+ zoomingState: ZoomingState;
}
> {
+ isPanning: boolean;
constructor(props: ImageComponentProps) {
super(props);
+ this.isPanning = false;
this.state = {
imageError: false,
+ zoomingState: ZoomingState.MAX_ZOOMED_OUT,
};
}
render() {
+ const { maxZoomLevel } = this.props;
+ const zoomActive =
+ maxZoomLevel !== undefined && maxZoomLevel > 1 && !this.isPanning;
+ const isZoomingIn = this.state.zoomingState === ZoomingState.MAX_ZOOMED_OUT;
+ let cursor = "inherit";
+ if (zoomActive) {
+ cursor = isZoomingIn ? "zoom-in" : "zoom-out";
+ }
return (
-
-
+ {
+ this.props.disableDrag(true);
}}
- alt={this.props.widgetName}
- src={this.props.imageUrl}
- onError={this.onImageError}
- onLoad={this.onImageLoad}
- onClick={this.props.onClick}
- >
-
+ onPanning={() => {
+ this.isPanning = true;
+ }}
+ onPanningStop={() => {
+ this.props.disableDrag(false);
+ }}
+ options={{
+ maxScale: maxZoomLevel,
+ disabled: !zoomActive,
+ transformEnabled: zoomActive,
+ }}
+ pan={{
+ disabled: !zoomActive,
+ }}
+ wheel={{
+ disabled: !zoomActive,
+ }}
+ doubleClick={{
+ disabled: true,
+ }}
+ onZoomChange={(zoom: any) => {
+ if (zoomActive) {
+ //Check max zoom
+ if (
+ maxZoomLevel === zoom.scale &&
+ // Added for preventing infinite loops
+ this.state.zoomingState !== ZoomingState.MAX_ZOOMED_IN
+ ) {
+ this.setState({
+ zoomingState: ZoomingState.MAX_ZOOMED_IN,
+ });
+ // Check min zoom
+ } else if (
+ zoom.scale === 1 &&
+ this.state.zoomingState !== ZoomingState.MAX_ZOOMED_OUT
+ ) {
+ this.setState({
+ zoomingState: ZoomingState.MAX_ZOOMED_OUT,
+ });
+ }
+ }
+ }}
+ >
+ {({ zoomIn, zoomOut, setScale, ...rest }: any) => (
+
+
+ ) => {
+ if (!this.isPanning) {
+ if (isZoomingIn) {
+ zoomIn(event);
+ } else {
+ zoomOut(event);
+ }
+ this.props.onClick && this.props.onClick(event);
+ }
+ this.isPanning = false;
+ }}
+ >
+
+
+
+
+ )}
+
+
);
}
@@ -82,6 +179,8 @@ export interface ImageComponentProps extends ComponentProps {
defaultImageUrl: string;
isLoading: boolean;
showHoverPointer?: boolean;
+ maxZoomLevel: number;
+ disableDrag: (disabled: boolean) => void;
onClick?: (event: React.MouseEvent) => void;
}
diff --git a/app/client/src/components/designSystems/appsmith/MapComponent.tsx b/app/client/src/components/designSystems/appsmith/MapComponent.tsx
index 80fa6067b6..09282d6df8 100644
--- a/app/client/src/components/designSystems/appsmith/MapComponent.tsx
+++ b/app/client/src/components/designSystems/appsmith/MapComponent.tsx
@@ -73,62 +73,80 @@ const PickMyLocationWrapper = styled.div`
`;
const MyMapComponent = withScriptjs(
- withGoogleMap((props: any) => (
- {
- if (props.enableCreateMarker) {
- props.saveMarker(e.latLng.lat(), e.latLng.lng());
+ withGoogleMap((props: any) => {
+ const [mapCenter, setMapCenter] = React.useState<
+ | {
+ lat: number;
+ lng: number;
+ title?: string;
+ description?: string;
}
- }}
- >
- {props.enableSearch && (
-
-
-
- )}
- {props.markers.map((marker: any, index: number) => (
- ({
+ ...props.center,
+ lng: props.center.long,
+ });
+ return (
+ {
+ if (props.enableCreateMarker) {
+ props.saveMarker(e.latLng.lat(), e.latLng.lng());
}
- onClick={e => {
- props.selectMarker(marker.lat, marker.long, marker.title);
- }}
- onDragEnd={de => {
- props.updateMarker(de.latLng.lat(), de.latLng.lng(), index);
- }}
- />
- ))}
- {props.enablePickLocation && (
-
-
-
- )}
-
- )),
+ }}
+ >
+ {props.enableSearch && (
+
+
+
+ )}
+ {props.markers.map((marker: any, index: number) => (
+ {
+ setMapCenter({
+ ...marker,
+ lng: marker.long,
+ });
+ props.selectMarker(marker.lat, marker.long, marker.title);
+ }}
+ onDragEnd={de => {
+ props.updateMarker(de.latLng.lat(), de.latLng.lng(), index);
+ }}
+ />
+ ))}
+ {props.enablePickLocation && (
+
+
+
+ )}
+
+ );
+ }),
);
class MapComponent extends React.Component {
diff --git a/app/client/src/components/designSystems/appsmith/ReactTableComponent.tsx b/app/client/src/components/designSystems/appsmith/ReactTableComponent.tsx
index b0fb1f2a09..03dea321db 100644
--- a/app/client/src/components/designSystems/appsmith/ReactTableComponent.tsx
+++ b/app/client/src/components/designSystems/appsmith/ReactTableComponent.tsx
@@ -42,16 +42,16 @@ interface ReactTableComponentProps {
width: number;
height: number;
pageSize: number;
- tableData: object[];
+ tableData: Array>;
columnOrder?: string[];
disableDrag: (disable: boolean) => void;
- onRowClick: (rowData: object, rowIndex: number) => void;
+ onRowClick: (rowData: Record, rowIndex: number) => void;
onCommandClick: (dynamicTrigger: string, onComplete: () => void) => void;
- updatePageNo: Function;
+ updatePageNo: (pageNo: number) => void;
updateHiddenColumns: (hiddenColumns?: string[]) => void;
sortTableColumn: (column: string, asc: boolean) => void;
- nextPageClick: Function;
- prevPageClick: Function;
+ nextPageClick: () => void;
+ prevPageClick: () => void;
pageNo: number;
serverSidePaginationEnabled: boolean;
columnActions?: ColumnAction[];
@@ -68,10 +68,12 @@ interface ReactTableComponentProps {
};
};
columnSizeMap?: { [key: string]: number };
- updateColumnType: Function;
- updateColumnName: Function;
- handleResizeColumn: Function;
- handleReorderColumn: Function;
+ updateColumnType: (columnTypeMap: {
+ [key: string]: { type: string; format: string };
+ }) => void;
+ updateColumnName: (columnNameMap: { [key: string]: string }) => void;
+ handleResizeColumn: (columnSizeMap: { [key: string]: number }) => void;
+ handleReorderColumn: (columnOrder: string[]) => void;
searchTableData: (searchKey: any) => void;
filters?: ReactTableFilter[];
applyFilter: (filters: ReactTableFilter[]) => void;
@@ -277,7 +279,7 @@ const ReactTableComponent = (props: ReactTableComponentProps) => {
};
const selectTableRow = (
- row: { original: object; index: number },
+ row: { original: Record; index: number },
isSelected: boolean,
) => {
if (!isSelected || !!props.multiRowSelection) {
diff --git a/app/client/src/components/designSystems/appsmith/Table.tsx b/app/client/src/components/designSystems/appsmith/Table.tsx
index 824b33f5e3..51b6b6619b 100644
--- a/app/client/src/components/designSystems/appsmith/Table.tsx
+++ b/app/client/src/components/designSystems/appsmith/Table.tsx
@@ -32,19 +32,19 @@ interface TableProps {
columns: ReactTableColumnProps[];
hiddenColumns?: string[];
updateHiddenColumns: (hiddenColumns?: string[]) => void;
- data: object[];
+ data: Array>;
editMode: boolean;
columnNameMap?: { [key: string]: string };
getColumnMenu: (columnIndex: number) => ColumnMenuOptionProps[];
handleColumnNameUpdate: (columnIndex: number, columnName: string) => void;
sortTableColumn: (columnIndex: number, asc: boolean) => void;
- handleResizeColumn: Function;
+ handleResizeColumn: (columnIndex: number, columnWidth: string) => void;
selectTableRow: (
- row: { original: object; index: number },
+ row: { original: Record; index: number },
isSelected: boolean,
) => void;
pageNo: number;
- updatePageNo: Function;
+ updatePageNo: (pageNo: number) => void;
nextPageClick: () => void;
prevPageClick: () => void;
serverSidePaginationEnabled: boolean;
diff --git a/app/client/src/components/designSystems/appsmith/TableUtilities.tsx b/app/client/src/components/designSystems/appsmith/TableUtilities.tsx
index 14e379d213..efe2f6a6b6 100644
--- a/app/client/src/components/designSystems/appsmith/TableUtilities.tsx
+++ b/app/client/src/components/designSystems/appsmith/TableUtilities.tsx
@@ -688,7 +688,7 @@ export const TableHeaderCell = (props: {
handleColumnNameUpdate: (columnIndex: number, name: string) => void;
getColumnMenu: (columnIndex: number) => ColumnMenuOptionProps[];
sortTableColumn: (columnIndex: number, asc: boolean) => void;
- handleResizeColumn: Function;
+ handleResizeColumn: (columnIndex: number, columnWidth: string) => void;
column: any;
}) => {
const { column } = props;
@@ -765,7 +765,9 @@ export const TableHeaderCell = (props: {
);
};
-export const getAllTableColumnKeys = (tableData: object[]) => {
+export const getAllTableColumnKeys = (
+ tableData: Array>,
+) => {
const columnKeys: string[] = [];
for (let i = 0, tableRowCount = tableData.length; i < tableRowCount; i++) {
const row = tableData[i];
@@ -814,7 +816,7 @@ export const reorderColumns = (
};
export function sortTableFunction(
- filteredTableData: object[],
+ filteredTableData: Array>,
columns: ReactTableColumnProps[],
sortedColumn: string,
sortOrder: boolean,
@@ -881,7 +883,10 @@ export const ConditionFunctions: {
return a !== "" && a !== undefined && a !== null;
},
notEqualTo: (a: any, b: any) => {
- return a !== b;
+ return a.toString() !== b.toString();
+ },
+ isEqualTo: (a: any, b: any) => {
+ return a.toString() === b.toString();
},
lessThan: (a: any, b: any) => {
const numericB = Number(b);
diff --git a/app/client/src/components/editorComponents/LightningMenu/helpers.tsx b/app/client/src/components/editorComponents/LightningMenu/helpers.tsx
index 91ac42aa1a..b17dc48058 100644
--- a/app/client/src/components/editorComponents/LightningMenu/helpers.tsx
+++ b/app/client/src/components/editorComponents/LightningMenu/helpers.tsx
@@ -62,7 +62,7 @@ export const getApiOptions = (
text: LIGHTNING_MENU_DATA_API,
},
openDirection: Directions.RIGHT,
- openOnHover: false,
+ openOnHover: true,
skin: skin,
modifiers: {
offset: {
@@ -111,7 +111,7 @@ export const getQueryOptions = (
text: LIGHTNING_MENU_DATA_QUERY,
},
openDirection: Directions.RIGHT,
- openOnHover: false,
+ openOnHover: true,
skin: skin,
modifiers: {
offset: {
@@ -141,7 +141,7 @@ export const getWidgetOptions = (
text: LIGHTNING_MENU_DATA_WIDGET,
},
openDirection: Directions.RIGHT,
- openOnHover: false,
+ openOnHover: true,
skin: skin,
modifiers: {
offset: {
diff --git a/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx b/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
index 5f24b8150d..2ee33c83d7 100644
--- a/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
+++ b/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
@@ -18,7 +18,7 @@ import { KeyValueComponent } from "components/propertyControls/KeyValueComponent
import { InputText } from "components/propertyControls/InputTextControl";
import { createModalAction } from "actions/widgetActions";
import { createNewApiName, createNewQueryName } from "utils/AppsmithUtils";
-import { isDynamicValue } from "utils/DynamicBindingUtils";
+import { getDynamicBindings, isDynamicValue } from "utils/DynamicBindingUtils";
import HightlightedCode from "components/editorComponents/HighlightedCode";
import TreeStructure from "components/utils/TreeStructure";
import {
@@ -46,6 +46,7 @@ const FILE_TYPE_OPTIONS = [
{ label: "SVG", value: "'image/svg+xml'", id: "image/svg+xml" },
];
+const FUNC_ARGS_REGEX = /((["][^"]*["])|(['][^']*['])|([\(].*[\)[=][>][{].*[}])|([^'",][^,"+]*[^'",]*))*/gi;
const ACTION_TRIGGER_REGEX = /^{{([\s\S]*?)\(([\s\S]*?)\)}}$/g;
//Old Regex:: /\(\) => ([\s\S]*?)(\([\s\S]*?\))/g;
const ACTION_ANONYMOUS_FUNC_REGEX = /\(\) => (({[\s\S]*?})|([\s\S]*?)(\([\s\S]*?\)))/g;
@@ -78,23 +79,51 @@ export const modalGetter = (value: string) => {
return name;
};
-// const urlSetter = (changeValue: any, currentValue: string): string => {
-// return currentValue.replace(ACTION_TRIGGER_REGEX, `{{$1('${changeValue}')}}`);
-// };
+const stringToJS = (string: string): string => {
+ const { stringSegments, jsSnippets } = getDynamicBindings(string);
+ const js = stringSegments
+ .map((segment, index) => {
+ if (jsSnippets[index] && jsSnippets[index].length > 0) {
+ return jsSnippets[index];
+ } else {
+ return `'${segment}'`;
+ }
+ })
+ .join(" + ");
+ return js;
+};
-// export const textGetter = (value: string) => {
-// const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
-// if (matches.length) {
-// const stringValue = matches[0][2];
-// return stringValue.substring(1, stringValue.length - 1);
-// }
-// return "";
-// };
+const JSToString = (js: string): string => {
+ const segments = js.split(" + ");
+ return segments
+ .map(segment => {
+ if (segment.charAt(0) === "'") {
+ return segment.substring(1, segment.length - 1);
+ } else return "{{" + segment + "}}";
+ })
+ .join("");
+};
-const alertTextSetter = (changeValue: any, currentValue: string): string => {
+const argsStringToArray = (funcArgs: string): string[] => {
+ const argsplitMatches = [...funcArgs.matchAll(FUNC_ARGS_REGEX)];
+ return argsplitMatches
+ .map(match => {
+ return match[0];
+ })
+ .filter(arg => {
+ return arg !== "";
+ });
+};
+
+const textSetter = (
+ changeValue: any,
+ currentValue: string,
+ argNum: number,
+): string => {
const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[0] = `'${changeValue}'`;
+ const args = argsStringToArray(matches[0][2]);
+ const jsVal = stringToJS(changeValue);
+ args[argNum] = jsVal;
const result = currentValue.replace(
ACTION_TRIGGER_REGEX,
`{{$1(${args.join(",")})}}`,
@@ -102,40 +131,25 @@ const alertTextSetter = (changeValue: any, currentValue: string): string => {
return result;
};
-const alertTextGetter = (value: string) => {
+const textGetter = (value: string, argNum: number) => {
const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[0];
- return arg.substring(1, arg.length - 1);
+ const args = argsStringToArray(matches[0][2]);
+ const arg = args[argNum];
+ const stringFromJS = arg ? JSToString(arg.trim()) : arg;
+ return stringFromJS;
}
return "";
};
-const alertTypeSetter = (changeValue: any, currentValue: string): string => {
+const enumTypeSetter = (
+ changeValue: any,
+ currentValue: string,
+ argNum: number,
+): string => {
const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[1] = changeValue as string;
- return currentValue.replace(
- ACTION_TRIGGER_REGEX,
- `{{$1(${args.join(",")})}}`,
- );
-};
-
-const alertTypeGetter = (value: string) => {
- const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
- if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[1];
- return arg ? arg.trim() : "'primary'";
- }
- return "";
-};
-
-const storeKeyTextSetter = (changeValue: any, currentValue: string): string => {
- const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[0] = `'${changeValue}'`;
+ const args = argsStringToArray(matches[0][2]);
+ args[argNum] = changeValue as string;
const result = currentValue.replace(
ACTION_TRIGGER_REGEX,
`{{$1(${args.join(",")})}}`,
@@ -143,104 +157,18 @@ const storeKeyTextSetter = (changeValue: any, currentValue: string): string => {
return result;
};
-const storeKeyTextGetter = (value: string) => {
- const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
- if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[0];
- return arg.substring(1, arg.length - 1);
- }
- return "";
-};
-
-const storeValueTextSetter = (
- changeValue: any,
- currentValue: string,
+const enumTypeGetter = (
+ value: string,
+ argNum: number,
+ defaultValue = "",
): string => {
- const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[1] = `'${changeValue}'`;
- return currentValue.replace(
- ACTION_TRIGGER_REGEX,
- `{{$1(${args.join(",")})}}`,
- );
-};
-
-const storeValueTextGetter = (value: string) => {
const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[1];
- return arg ? arg.substring(1, arg.length - 1) : "";
+ const args = argsStringToArray(matches[0][2]);
+ const arg = args[argNum];
+ return arg ? arg.trim() : defaultValue;
}
- return "";
-};
-
-const downloadDataSetter = (changeValue: any, currentValue: string): string => {
- const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[0] = `'${changeValue}'`;
- const result = currentValue.replace(
- ACTION_TRIGGER_REGEX,
- `{{$1(${args.join(",")})}}`,
- );
- return result;
-};
-
-const downloadDataGetter = (value: string) => {
- const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
- if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[0];
- return arg.substring(1, arg.length - 1);
- }
- return "";
-};
-
-const downloadFileNameSetter = (
- changeValue: any,
- currentValue: string,
-): string => {
- const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[1] = `'${changeValue}'`;
- return currentValue.replace(
- ACTION_TRIGGER_REGEX,
- `{{$1(${args.join(",")})}}`,
- );
-};
-
-const downloadFileNameGetter = (value: string) => {
- const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
- if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[1];
- return arg ? arg.substring(1, arg.length - 1) : "";
- }
- return "";
-};
-
-const downloadFileTypeSetter = (
- changeValue: any,
- currentValue: string,
-): string => {
- const matches = [...currentValue.matchAll(ACTION_TRIGGER_REGEX)];
- const args = matches[0][2].split(",");
- args[2] = changeValue as string;
- return currentValue.replace(
- ACTION_TRIGGER_REGEX,
- `{{$1(${args.join(",")})}}`,
- );
-};
-
-const downloadFileTypeGetter = (value: string) => {
- const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
- if (matches.length) {
- const funcArgs = matches[0][2];
- const arg = funcArgs.split(",")[2];
- return arg ? arg.trim() : "";
- }
- return "";
+ return defaultValue;
};
type ActionCreatorProps = {
@@ -436,10 +364,10 @@ const fieldConfigs: FieldConfigs = {
},
[FieldType.PAGE_SELECTOR_FIELD]: {
getter: (value: any) => {
- return modalGetter(value);
+ return textGetter(value, 0);
},
setter: (option: any, currentValue: string) => {
- return modalSetter(option.value, currentValue);
+ return textSetter(option, currentValue, 0);
},
view: ViewTypes.SELECTOR_VIEW,
},
@@ -454,55 +382,73 @@ const fieldConfigs: FieldConfigs = {
},
[FieldType.URL_FIELD]: {
getter: (value: string) => {
- return modalGetter(value);
+ return textGetter(value, 0);
},
setter: (value: string, currentValue: string) => {
- return modalSetter(value, currentValue);
+ return textSetter(value, currentValue, 0);
},
view: ViewTypes.TEXT_VIEW,
},
[FieldType.ALERT_TEXT_FIELD]: {
getter: (value: string) => {
- return alertTextGetter(value);
+ return textGetter(value, 0);
},
setter: (value: string, currentValue: string) => {
- return alertTextSetter(value, currentValue);
+ return textSetter(value, currentValue, 0);
},
view: ViewTypes.TEXT_VIEW,
},
[FieldType.ALERT_TYPE_SELECTOR_FIELD]: {
getter: (value: any) => {
- return alertTypeGetter(value);
+ return enumTypeGetter(value, 1, "success");
},
setter: (option: any, currentValue: string) => {
- return alertTypeSetter(option.value, currentValue);
+ return enumTypeSetter(option.value, currentValue, 1);
},
view: ViewTypes.SELECTOR_VIEW,
},
[FieldType.KEY_TEXT_FIELD]: {
- getter: storeKeyTextGetter,
- setter: storeKeyTextSetter,
+ getter: (value: any) => {
+ return textGetter(value, 0);
+ },
+ setter: (option: any, currentValue: string) => {
+ return textSetter(option, currentValue, 0);
+ },
view: ViewTypes.TEXT_VIEW,
},
[FieldType.VALUE_TEXT_FIELD]: {
- getter: storeValueTextGetter,
- setter: storeValueTextSetter,
+ getter: (value: any) => {
+ return textGetter(value, 1);
+ },
+ setter: (option: any, currentValue: string) => {
+ return textSetter(option, currentValue, 1);
+ },
view: ViewTypes.TEXT_VIEW,
},
[FieldType.DOWNLOAD_DATA_FIELD]: {
- getter: downloadDataGetter,
- setter: downloadDataSetter,
+ getter: (value: any) => {
+ return textGetter(value, 0);
+ },
+ setter: (option: any, currentValue: string) => {
+ return textSetter(option, currentValue, 0);
+ },
view: ViewTypes.TEXT_VIEW,
},
[FieldType.DOWNLOAD_FILE_NAME_FIELD]: {
- getter: downloadFileNameGetter,
- setter: downloadFileNameSetter,
+ getter: (value: any) => {
+ return textGetter(value, 1);
+ },
+ setter: (option: any, currentValue: string) => {
+ return textSetter(option, currentValue, 1);
+ },
view: ViewTypes.TEXT_VIEW,
},
[FieldType.DOWNLOAD_FILE_TYPE_FIELD]: {
- getter: downloadFileTypeGetter,
+ getter: (value: any) => {
+ return enumTypeGetter(value, 2);
+ },
setter: (option: any, currentValue: string) =>
- downloadFileTypeSetter(option.value, currentValue),
+ enumTypeSetter(option.value, currentValue, 2),
view: ViewTypes.SELECTOR_VIEW,
},
};
diff --git a/app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx b/app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx
index 99200a880b..a83a90a5d8 100644
--- a/app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx
+++ b/app/client/src/components/editorComponents/form/fields/DropdownWrapper.tsx
@@ -19,10 +19,10 @@ const DropdownWrapper = (props: DropdownWrapperProps) => {
};
useEffect(() => {
- if (props.placeholder) {
- setSelectedOption({ value: props.placeholder });
- } else if (props.input && props.input.value) {
+ if (props.input && props.input.value) {
setSelectedOption({ value: props.input.value });
+ } else if (props.placeholder) {
+ setSelectedOption({ value: props.placeholder });
}
}, [props.input, props.placeholder]);
diff --git a/app/client/src/components/editorComponents/form/fields/TagListField.tsx b/app/client/src/components/editorComponents/form/fields/TagListField.tsx
index a2d38ccb27..ca30384eb9 100644
--- a/app/client/src/components/editorComponents/form/fields/TagListField.tsx
+++ b/app/client/src/components/editorComponents/form/fields/TagListField.tsx
@@ -26,6 +26,7 @@ type TagListFieldProps = {
type: string;
label: string;
intent: Intent;
+ customError: (err: string) => void;
};
const TagListField = (props: TagListFieldProps) => {
diff --git a/app/client/src/components/formControls/DynamicTextFieldControl.tsx b/app/client/src/components/formControls/DynamicTextFieldControl.tsx
index c8928db33a..bc4e5aa933 100644
--- a/app/client/src/components/formControls/DynamicTextFieldControl.tsx
+++ b/app/client/src/components/formControls/DynamicTextFieldControl.tsx
@@ -25,7 +25,7 @@ const Wrapper = styled.div`
.dynamic-text-field {
border-radius: 4px;
font-size: 14px;
- height: calc(100vh / 4);
+ min-height: calc(100vh / 4);
}
&& {
@@ -98,7 +98,7 @@ class DynamicTextControl extends BaseControl<
export interface DynamicTextFieldProps extends ControlProps {
actionName: string;
- createTemplate: Function;
+ createTemplate: (template: any) => any;
pluginId: string;
responseType: string;
}
diff --git a/app/client/src/components/formControls/InputTextControl.tsx b/app/client/src/components/formControls/InputTextControl.tsx
index 52a7bcb4a7..75f26e73e6 100644
--- a/app/client/src/components/formControls/InputTextControl.tsx
+++ b/app/client/src/components/formControls/InputTextControl.tsx
@@ -4,6 +4,17 @@ import { InputType } from "widgets/InputWidget";
import { ControlType } from "constants/PropertyControlConstants";
import TextField from "components/editorComponents/form/fields/TextField";
import FormLabel from "components/editorComponents/FormLabel";
+import { FormIcons } from "icons/FormIcons";
+import { Colors } from "constants/Colors";
+import styled from "styled-components";
+
+const StyledInfo = styled.span`
+ font-weight: normal;
+ line-height: normal;
+ color: ${Colors.CADET_BLUE};
+ font-size: 12px;
+ margin-left: 1px;
+`;
export function InputText(props: {
label: string;
@@ -14,13 +25,20 @@ export function InputText(props: {
dataType?: string;
isRequired?: boolean;
name: string;
+ encrypted?: boolean;
}) {
const { name, placeholder, dataType, label, isRequired } = props;
return (
+
+ Secure & fast database connection
+
+ Connect your database to start building read/write workflows. Your
+ Passwords are fully encrypted and we never store any of your data.
+ Thatโs a promise.
+
+
+