Merge pull request #4071 from appsmithorg/release

Release Patch 2
This commit is contained in:
Trisha Anand 2021-04-20 15:41:58 +05:30 committed by GitHub
commit 04601b5bcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 194 additions and 34 deletions

View File

@ -6,7 +6,7 @@
</p>
<p align="center">
<a href="https://app.appsmith.com/signup"><strong>Try Online Sandbox</strong></a>
<a href="https://app.appsmith.com/signup?utm_source=github&utm_medium=social&utm_content=website&utm_campaign=null&utm_term=website"><strong>Try Online Sandbox</strong></a>
</p>
<p align="center">
<a href="https://docs.appsmith.com/">Documentation</a>
@ -63,7 +63,7 @@ But if youd 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

View File

@ -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",

View File

@ -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"
}
]
}
}

View File

@ -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");

View File

@ -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 });
});
});

View File

@ -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()

View File

@ -239,6 +239,7 @@ class EmbeddedDatasourcePathComponent extends React.Component<Props> {
<StoreAsDatasource enable={!!displayValue} />
) : datasource && "id" in datasource ? (
<DatasourceIcon
enable={true}
onClick={() =>
history.push(
DATA_SOURCES_EDITOR_ID_URL(

View File

@ -102,4 +102,3 @@ div.bp3-popover-arrow {
background: white !important;
border-bottom: 1px solid #E7E7E7 !important;
}

View File

@ -29,6 +29,7 @@ const PostBodyContainer = styled.div`
const JSONEditorFieldWrapper = styled.div`
margin: 0 30px;
width: 65%;
.CodeMirror {
height: auto;
min-height: 250px;

View File

@ -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());
}
},

View File

@ -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,

View File

@ -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,

View File

@ -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<CandidateField> 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<String, String> 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();

View File

@ -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);
// }
}

View File

@ -287,7 +287,9 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
if (datasource.getDatasourceConfiguration() != null
&& !CollectionUtils.isEmpty(datasource.getDatasourceConfiguration().getEndpoints())) {
for (final Endpoint endpoint : datasource.getDatasourceConfiguration().getEndpoints()) {
endpoint.setHost(endpoint.getHost().trim());
if (endpoint != null && endpoint.getHost() != null) {
endpoint.setHost(endpoint.getHost().trim());
}
}
}