diff --git a/README.md b/README.md index 7488dc2567..2f0080c996 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

- Try Online Sandbox + Try Online Sandbox

Documentation @@ -63,7 +63,7 @@ But if you’d rather check out some real applications that can be built with Ap 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](https://docs.appsmith.com/setup). +1. [Sign up on Appsmith Cloud](https://app.appsmith.com/signup?utm_source=github&utm_medium=social&utm_content=website&utm_campaign=null&utm_term=website) or [Deploy Appsmith](https://docs.appsmith.com/setup). 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`. @@ -79,12 +79,12 @@ Connect your own data to build apps for your team. [Read more here.](https://doc ## 📚 Tutorials 1. [Building an Admin Panel on MongoDB using Appsmith](https://blog.appsmith.com/building-an-admin-panel-with-mongodb-using-appsmith) ([Video](https://www.youtube.com/watch?v=tisUaIgI86k)) -2. [Building a customer support dashboard in Appsmith](https://www.youtube.com/watch?v=-O_6OLREEzo&t=272s) -3. [Running CI/CD jobs manually using Appsmith](https://blog.appsmith.com/how-to-run-manual-jobs-in-gitlab-cicd) ([Video](https://www.youtube.com/watch?v=CYdeJcD4I8A)) -4. [Building a calendly clone in Appsmith](https://blog.appsmith.com/how-to-build-a-calendly-clone-in-30-minutes) -5. [Building Internal Tools with Appsmith](https://youtu.be/eYYYfuW-kEE) `Community` -6. [Building an Issue Tracker with Appsmith](https://dev.to/pjmantoss/how-to-build-an-issue-tracker-with-appsmith-204e) `Community` - +2. [Building a Customer Support Dashboard in Appsmith](https://www.youtube.com/watch?v=-O_6OLREEzo&t=272s) +3. [Building a Store Catalogue Management System using Appsmith and GraphQL](https://blog.appsmith.com/building-a-store-catalogue-management-system-using-appsmith-and-graphql) +4. [Running CI/CD Jobs Manually using Appsmith](https://blog.appsmith.com/how-to-run-manual-jobs-in-gitlab-cicd) ([Video](https://www.youtube.com/watch?v=CYdeJcD4I8A)) +5. [Building a Calendly Clone in Appsmith](https://blog.appsmith.com/how-to-build-a-calendly-clone-in-30-minutes) +6. [Building Internal Tools with Appsmith](https://youtu.be/eYYYfuW-kEE) `Community` +7. [Building an Issue Tracker with Appsmith](https://dev.to/pjmantoss/how-to-build-an-issue-tracker-with-appsmith-204e) `Community` ## 📕 Support & Troubleshooting diff --git a/app/client/cypress/fixtures/example.json b/app/client/cypress/fixtures/example.json index 3e446160e2..598a710a31 100644 --- a/app/client/cypress/fixtures/example.json +++ b/app/client/cypress/fixtures/example.json @@ -102,6 +102,7 @@ "AlertModalName": "Alert_Modal", "FormModalName": "Form_Modal", "TextLabelValue": "Test Text Label", + "TextLabelValueScrollable": "Test Text Label to check scroll feature", "TextName": "TestTextBox", "TextLabel": "Paragraph", "TextBody": "Heading 2", diff --git a/app/client/cypress/fixtures/textDsl.json b/app/client/cypress/fixtures/textDsl.json new file mode 100644 index 0000000000..d9821d17da --- /dev/null +++ b/app/client/cypress/fixtures/textDsl.json @@ -0,0 +1,45 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 966, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 240, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 16, + "minHeight": 280, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "text": "Label", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "widgetName": "Text1", + "version": 1, + "type": "TEXT_WIDGET", + "isLoading": false, + "parentColumnSpace": 57.875, + "parentRowSpace": 40, + "leftColumn": 4, + "rightColumn": 8, + "topRow": 1, + "bottomRow": 2, + "parentId": "0", + "widgetId": "266vj9u1mr" + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_PropertyPane_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_PropertyPane_spec.js index 8329b92cda..1f2035eeab 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_PropertyPane_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_PropertyPane_spec.js @@ -10,21 +10,8 @@ describe("Table Widget property pane feature validation", function() { cy.addDsl(dsl); }); - it("Check collapse section feature in property pane", function() { - cy.openPropertyPane("tablewidget"); - //check open and collapse - cy.get(commonlocators.collapsesection) - .first() - .should("be.visible") - .click(); - cy.assertControlVisibility("tabledata"); - }); - it("Check open section and column data in property pane", function() { - cy.get(commonlocators.collapsesection) - .scrollIntoView() - .first() - .click(); + cy.openPropertyPane("tablewidget"); cy.tableColumnDataValidation("id"); cy.tableColumnDataValidation("email"); cy.tableColumnDataValidation("userName"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_new_feature_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_new_feature_spec.js new file mode 100644 index 0000000000..a35162eca6 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_new_feature_spec.js @@ -0,0 +1,109 @@ +const commonlocators = require("../../../../locators/commonlocators.json"); +const widgetsPage = require("../../../../locators/Widgets.json"); +const publishPage = require("../../../../locators/publishWidgetspage.json"); +const dsl = require("../../../../fixtures/textDsl.json"); +const pages = require("../../../../locators/Pages.json"); + +describe("Text Widget color/font/alignment Functionality", function() { + before(() => { + cy.addDsl(dsl); + }); + + beforeEach(() => { + cy.openPropertyPane("textwidget"); + }); + + it("Text-TextStyle Heading, Text Name Validation", function() { + //changing the Text Name and verifying + cy.widgetText( + this.data.TextName, + widgetsPage.textWidget, + widgetsPage.textWidget + " " + commonlocators.widgetNameTag, + ); + + //Changing the text label + cy.testCodeMirror(this.data.TextLabelValueScrollable); + + cy.ChangeTextStyle( + this.data.TextHeading, + commonlocators.headingTextStyle, + this.data.TextLabelValueScrollable, + ); + cy.wait("@updateLayout"); + cy.PublishtheApp(); + cy.get(commonlocators.headingTextStyle) + .should("have.text", this.data.TextLabelValueScrollable) + .should("have.css", "font-size", "24px"); + cy.get(publishPage.backToEditor).click({ force: true }); + }); + + it("Test to validate text format", function() { + //Changing the Text Style's and validating + cy.get(widgetsPage.italics).click({ force: true }); + cy.readTextDataValidateCSS("font-style", "italic"); + cy.get(widgetsPage.bold).click({ force: true }); + cy.readTextDataValidateCSS("font-weight", "400"); + cy.get(widgetsPage.bold).click({ force: true }); + cy.readTextDataValidateCSS("font-weight", "700"); + cy.get(widgetsPage.italics).click({ force: true }); + cy.readTextDataValidateCSS("font-style", "normal"); + cy.closePropertyPane(); + }); + + it("Test to validate color changes in text and background", function() { + //Changing the Text Style's and validating + cy.get(widgetsPage.textColor) + .first() + .click({ force: true }); + cy.xpath(widgetsPage.greenColor).click(); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(500); + cy.wait("@updateLayout"); + cy.readTextDataValidateCSS("color", "rgb(3, 179, 101)"); + cy.get(widgetsPage.textColor) + .clear({ force: true }) + .type("purple", { force: true }); + cy.wait("@updateLayout"); + cy.readTextDataValidateCSS("color", "rgb(128, 0, 128)"); + cy.get(widgetsPage.backgroundColor) + .first() + .click({ force: true }); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(500); + cy.xpath(widgetsPage.greenColor) + .first() + .click(); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(500); + cy.wait("@updateLayout"); + cy.PublishtheApp(); + cy.get(publishPage.backToEditor).click({ force: true }); + }); + + it("Test to validate text alignment", function() { + cy.get(widgetsPage.centerAlign) + .first() + .click({ force: true }); + cy.readTextDataValidateCSS("text-align", "center"); + cy.get(widgetsPage.rightAlign) + .first() + .click({ force: true }); + cy.readTextDataValidateCSS("text-align", "right"); + cy.get(widgetsPage.leftAlign) + .first() + .click({ force: true }); + cy.readTextDataValidateCSS("text-align", "left"); + cy.closePropertyPane(); + }); + + it("Test to validate enable scroll feature", function() { + cy.get(".t--property-control-enablescroll .bp3-switch").click({ + force: true, + }); + cy.wait("@updateLayout"); + cy.get(commonlocators.headingTextStyle).trigger("mouseover", { + force: true, + }); + cy.get(commonlocators.headingTextStyle).scrollIntoView({ duration: 2000 }); + }); +}); diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index fdfd69473f..958ccda954 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -1409,6 +1409,14 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add("readTextDataValidateCSS", (cssProperty, cssValue) => { + cy.get(commonlocators.headingTextStyle).should( + "have.css", + cssProperty, + cssValue, + ); +}); + Cypress.Commands.add("evaluateErrorMessage", (value) => { cy.get(commonlocators.evaluateMsg) .first() diff --git a/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx b/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx index 8203157e80..6851dc2745 100644 --- a/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx +++ b/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx @@ -239,6 +239,7 @@ class EmbeddedDatasourcePathComponent extends React.Component { ) : datasource && "id" in datasource ? ( history.push( DATA_SOURCES_EDITOR_ID_URL( diff --git a/app/client/src/index.css b/app/client/src/index.css index 9d0fe49e05..2ce8e9f6b7 100755 --- a/app/client/src/index.css +++ b/app/client/src/index.css @@ -102,4 +102,3 @@ div.bp3-popover-arrow { background: white !important; border-bottom: 1px solid #E7E7E7 !important; } - diff --git a/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx b/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx index 0a8b52b9f7..f5a6a93d8c 100644 --- a/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx +++ b/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx @@ -29,6 +29,7 @@ const PostBodyContainer = styled.div` const JSONEditorFieldWrapper = styled.div` margin: 0 30px; + width: 65%; .CodeMirror { height: auto; min-height: 250px; diff --git a/app/client/src/pages/Editor/PropertyPaneTitle.tsx b/app/client/src/pages/Editor/PropertyPaneTitle.tsx index 5543c7c982..83429616fd 100644 --- a/app/client/src/pages/Editor/PropertyPaneTitle.tsx +++ b/app/client/src/pages/Editor/PropertyPaneTitle.tsx @@ -121,7 +121,11 @@ const PropertyPaneTitle = memo((props: PropertyPaneTitleProps) => { const { title, updatePropertyTitle } = props; const updateNewTitle = useCallback( (value: string) => { - if (value && value.trim().length > 0 && value.trim() !== title.trim()) { + if ( + value && + value.trim().length > 0 && + value.trim() !== (title && title.trim()) + ) { updatePropertyTitle && updatePropertyTitle(value.trim()); } }, diff --git a/app/client/src/sagas/ApiPaneSagas.ts b/app/client/src/sagas/ApiPaneSagas.ts index ed6b112718..4ebdc80958 100644 --- a/app/client/src/sagas/ApiPaneSagas.ts +++ b/app/client/src/sagas/ApiPaneSagas.ts @@ -508,12 +508,12 @@ function* handleApiNameChangeSuccessSaga( if (!actionObj) { // Error case, log to sentry Toaster.show({ - text: createMessage(ERROR_ACTION_RENAME_FAIL, actionObj.name), + text: createMessage(ERROR_ACTION_RENAME_FAIL, ""), variant: Variant.danger, }); Sentry.captureException( - new Error(createMessage(ERROR_ACTION_RENAME_FAIL, actionObj.name)), + new Error(createMessage(ERROR_ACTION_RENAME_FAIL, "")), { extra: { actionId: actionId, diff --git a/app/client/src/sagas/QueryPaneSagas.ts b/app/client/src/sagas/QueryPaneSagas.ts index f75ebdb792..fab337d732 100644 --- a/app/client/src/sagas/QueryPaneSagas.ts +++ b/app/client/src/sagas/QueryPaneSagas.ts @@ -160,12 +160,12 @@ function* handleNameChangeSuccessSaga( if (!actionObj) { // Error case, log to sentry Toaster.show({ - text: createMessage(ERROR_ACTION_RENAME_FAIL, actionObj.name), + text: createMessage(ERROR_ACTION_RENAME_FAIL, ""), variant: Variant.danger, }); Sentry.captureException( - new Error(createMessage(ERROR_ACTION_RENAME_FAIL, actionObj.name)), + new Error(createMessage(ERROR_ACTION_RENAME_FAIL, "")), { extra: { actionId: actionId, diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java index b2d9225618..c6230b2b12 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/annotations/encryption/EncryptionHandler.java @@ -38,6 +38,9 @@ public class EncryptionHandler { // At this point source class represents the true polymorphic type of the document Class sourceClass = source.getClass(); + // Lock a thread wanting to find information about the same type + // So that this information retrieval is only done once + // Ignore this warning, this class reference will be on the heap List candidateFields = this.encryptedFieldsMap.get(sourceClass); if (candidateFields != null) { @@ -192,6 +195,7 @@ public class EncryptionHandler { encryptedFieldsMap.put(sourceClass, finalCandidateFields); return finalCandidateFields; + } boolean convertEncryption(Object source, Function transformer) { @@ -243,7 +247,6 @@ public class EncryptionHandler { // unknown types as polymorphic candidates over time // If that is the case then do we need to store the candidate field type by // known, unknown or polymorphic types at all? - // TODO Discuss w/ reviewer } } else { final Type[] typeNames = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java index be6ff0b7a2..16d9af3e2d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java @@ -79,9 +79,9 @@ public class MongoConfig { return converter; } - @Bean - public EncryptionMongoEventListener encryptionMongoEventListener(EncryptionService encryptionService) { - return new EncryptionMongoEventListener(encryptionService); - } +// @Bean +// public EncryptionMongoEventListener encryptionMongoEventListener(EncryptionService encryptionService) { +// return new EncryptionMongoEventListener(encryptionService); +// } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/DatasourceServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/DatasourceServiceImpl.java index e79882e143..b942a8bc37 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/DatasourceServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/DatasourceServiceImpl.java @@ -287,7 +287,9 @@ public class DatasourceServiceImpl extends BaseService