Merge pull request #1390 from appsmithorg/release

Release
This commit is contained in:
Hetu Nandu 2020-10-24 22:41:26 +05:30 committed by GitHub
commit d7e27be689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 250 additions and 24 deletions

View File

@ -14,9 +14,6 @@
<!-- ALL-CONTRIBUTORS-BADGE:END --> <!-- ALL-CONTRIBUTORS-BADGE:END -->
</p> </p>
<p>
<sub>Built with empathy, not just ❤︎ </sub>
</p>
</div> </div>
----------------- -----------------

View File

@ -0,0 +1,79 @@
{
"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": 1,
"rightColumn": 3,
"topRow": 1,
"bottomRow": 2,
"parentId": "0",
"widgetId": "p4777z9d4u",
"dynamicProperties": {}
},
{
"isVisible": true,
"inputType": "TEXT",
"label": "",
"widgetName": "Input1",
"type": "INPUT_WIDGET",
"isLoading": false,
"parentColumnSpace": 74,
"parentRowSpace": 40,
"leftColumn": 4,
"rightColumn": 9,
"topRow": 1,
"bottomRow": 2,
"parentId": "0",
"widgetId": "8pdmbhmd1p"
},
{
"isVisible": true,
"label": "",
"selectionType": "SINGLE_SELECT",
"options": "[{'label':'Vegetarian','value':'VEG'},{'label':'Non-Vegetarian','value':'NON_VEG'},{'label':'Vegan','value':'VEGAN'}]",
"widgetName": "Dropdown1",
"defaultOptionValue": "VEG",
"type": "DROP_DOWN_WIDGET",
"isLoading": false,
"parentColumnSpace": 74,
"parentRowSpace": 40,
"leftColumn": 10,
"rightColumn": 15,
"topRow": 1,
"bottomRow": 2,
"parentId": "0",
"widgetId": "cxum96myhf",
"dynamicBindings": {}
}
]
},
"layoutOnLoadActions": []
}

View File

@ -0,0 +1,43 @@
{
"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": "This is Page 1",
"textStyle": "HEADING",
"textAlign": "LEFT",
"widgetName": "Text1",
"type": "TEXT_WIDGET",
"isLoading": false,
"parentColumnSpace": 74,
"parentRowSpace": 40,
"leftColumn": 6,
"rightColumn": 10,
"topRow": 2,
"bottomRow": 4,
"parentId": "0",
"widgetId": "g338165fyp",
"dynamicBindings": {}
}
]
},
"layoutOnLoadActions": []
}

View File

@ -110,7 +110,7 @@
"RichTextEditorName": "RichtextEditor", "RichTextEditorName": "RichtextEditor",
"HtmlText": "This is the initial<b>content </b> <h1> This is a Heading</h1> <p> This is a paragraph.</p>", "HtmlText": "This is the initial<b>content </b> <h1> This is a Heading</h1> <p> This is a paragraph.</p>",
"RichTexteditorBody": "Here is the text area to edit html", "RichTexteditorBody": "Here is the text area to edit html",
"userApi": "http://postgrest.appsmith.com:3000", "userApi": "http://mock-api.appsmith.com",
"validateImage": "https://cdn.dribbble.com/users/1787323/screenshots/4563995/dribbbe_hammer-01.png", "validateImage": "https://cdn.dribbble.com/users/1787323/screenshots/4563995/dribbbe_hammer-01.png",
"defaultdata": "TestData", "defaultdata": "TestData",
"label": "one", "label": "one",
@ -174,4 +174,4 @@
], ],
"paginationUrl": "https://mock-api.appsmith.com/", "paginationUrl": "https://mock-api.appsmith.com/",
"paginationParam": "users?page={{Table1.pageNo}}&size={{Table1.pageSize }}" "paginationParam": "users?page={{Table1.pageNo}}&size={{Table1.pageSize }}"
} }

View File

@ -29,7 +29,7 @@ describe("Test Create Api and Bind to Table widget", function() {
it("Test_Validate the Api data is updated on Table widget", function() { it("Test_Validate the Api data is updated on Table widget", function() {
cy.SearchEntityandOpen("Table1"); cy.SearchEntityandOpen("Table1");
//cy.openPropertyPane("tablewidget"); //cy.openPropertyPane("tablewidget");
cy.testJsontext("tabledata", "{{Api1.data}}"); cy.testJsontext("tabledata", "{{Api1.data.users}}");
cy.get(commonlocators.editPropCrossButton).click(); cy.get(commonlocators.editPropCrossButton).click();
/** /**

View File

@ -0,0 +1,34 @@
const dsl = require("../../../fixtures/Js_toggle_dsl.json");
describe("JS Toggle tests", () => {
before(() => {
cy.addDsl(dsl);
});
it("switches the toggle to Button widget", () => {
cy.openPropertyPane("buttonwidget");
cy.get(".t--property-control-visible")
.find(".t--js-toggle")
.click();
cy.get(".t--property-control-visible")
.find(".t--js-toggle")
.should("have.class", "is-active");
cy.testJsontext("visible", "false");
cy.wait(1000);
cy.get(".t--property-control-visible")
.find(".t--js-toggle")
.click();
cy.get(".t--property-control-visible")
.find(".t--js-toggle")
.should("not.have.class", "is-active");
cy.get(".t--property-control-visible")
.find("input")
.should("not.have.attr", "checked");
});
});

View File

@ -0,0 +1,57 @@
const dsl = require("../../../fixtures/PageLoadDsl.json");
const commonlocators = require("../../../locators/commonlocators.json");
describe("Page Load tests", () => {
before(() => {
cy.addDsl(dsl);
cy.get("div")
.contains("Pages")
.next()
.click();
cy.get("h2").contains("Drag and drop a widget here");
cy.addDsl(dsl);
});
it("Published page loads correctly", () => {
// Update the text to be asserted later
cy.openPropertyPane("textwidget");
cy.testCodeMirror("This is Page 2");
// Publish
cy.PublishtheApp();
// Assert active page tab
cy.get(".t--page-switch-tab")
.contains("Page2")
.parent()
.should("have.class", "is-active");
// Assert active page DSL
cy.get(commonlocators.headingTextStyle).should(
"have.text",
"This is Page 2",
);
// Test after reload
cy.reload();
// Assert active page tab
cy.get(".t--page-switch-tab")
.contains("Page2")
.parent()
.should("have.class", "is-active");
// Assert active page DSL
cy.get(commonlocators.headingTextStyle).should(
"have.text",
"This is Page 2",
);
// Switch page
cy.get(".t--page-switch-tab")
.contains("Page1")
.click({ force: true });
// Assert active page tab
cy.get(".t--page-switch-tab")
.contains("Page1")
.parent()
.should("have.class", "is-active");
// Assert active page DSL
cy.get(commonlocators.headingTextStyle).should(
"have.text",
"This is Page 1",
);
});
});

View File

@ -10,6 +10,7 @@ import {
BASE_SIGNUP_URL, BASE_SIGNUP_URL,
BASE_URL, BASE_URL,
BUILDER_URL, BUILDER_URL,
getApplicationViewerPageURL,
ORG_URL, ORG_URL,
PAGE_NOT_FOUND_URL, PAGE_NOT_FOUND_URL,
SERVER_ERROR_URL, SERVER_ERROR_URL,
@ -88,6 +89,10 @@ class AppRouter extends React.Component<any, any> {
component={ApplicationListLoader} component={ApplicationListLoader}
/> />
<SentryRoute path={BUILDER_URL} component={EditorLoader} /> <SentryRoute path={BUILDER_URL} component={EditorLoader} />
<SentryRoute
path={getApplicationViewerPageURL()}
component={AppViewerLoader}
/>
<SentryRoute path={APP_VIEW_URL} component={AppViewerLoader} /> <SentryRoute path={APP_VIEW_URL} component={AppViewerLoader} />
<SentryRoute <SentryRoute
exact exact

View File

@ -34,7 +34,7 @@ const AppViewerBody = styled.section`
`; `;
export type AppViewerProps = { export type AppViewerProps = {
initializeAppViewer: Function; initializeAppViewer: (applicationId: string, pageId?: string) => void;
isInitialized: boolean; isInitialized: boolean;
executeAction: (actionPayload: ExecuteActionPayload) => void; executeAction: (actionPayload: ExecuteActionPayload) => void;
updateWidgetProperty: ( updateWidgetProperty: (
@ -61,9 +61,10 @@ class AppViewer extends Component<
editorInitializer().then(() => { editorInitializer().then(() => {
this.setState({ registered: true }); this.setState({ registered: true });
}); });
const { applicationId } = this.props.match.params; const { applicationId, pageId } = this.props.match.params;
if (this.props.match.params.applicationId) { console.log({ applicationId, pageId });
this.props.initializeAppViewer(applicationId); if (applicationId) {
this.props.initializeAppViewer(applicationId, pageId);
} }
} }
@ -125,11 +126,12 @@ const mapDispatchToProps = (dispatch: any) => ({
dispatch(updateWidgetMetaProperty(widgetId, propertyName, propertyValue)), dispatch(updateWidgetMetaProperty(widgetId, propertyName, propertyValue)),
resetChildrenMetaProperty: (widgetId: string) => resetChildrenMetaProperty: (widgetId: string) =>
dispatch(resetChildrenMetaProperty(widgetId)), dispatch(resetChildrenMetaProperty(widgetId)),
initializeAppViewer: (applicationId: string) => initializeAppViewer: (applicationId: string, pageId?: string) => {
dispatch({ dispatch({
type: ReduxActionTypes.INITIALIZE_PAGE_VIEWER, type: ReduxActionTypes.INITIALIZE_PAGE_VIEWER,
payload: { applicationId }, payload: { applicationId, pageId },
}), });
},
}); });
export default withRouter( export default withRouter(

View File

@ -249,6 +249,7 @@ export const AppViewerHeader = (props: AppViewerHeaderProps) => {
page.pageId, page.pageId,
)} )}
activeClassName="is-active" activeClassName="is-active"
className="t--page-switch-tab"
> >
<span>{page.pageName}</span> <span>{page.pageName}</span>
</PageTab> </PageTab>

View File

@ -107,6 +107,7 @@ const PropertyControl = (props: Props) => {
<JSToggleButton <JSToggleButton
active={isDynamic} active={isDynamic}
onClick={() => toggleDynamicProperty(propertyName, isDynamic)} onClick={() => toggleDynamicProperty(propertyName, isDynamic)}
className={`t--js-toggle ${isDynamic ? "is-active" : ""}`}
> >
<ControlIcons.JS_TOGGLE /> <ControlIcons.JS_TOGGLE />
</JSToggleButton> </JSToggleButton>

View File

@ -149,9 +149,9 @@ export function* populatePageDSLsSaga() {
} }
export function* initializeAppViewerSaga( export function* initializeAppViewerSaga(
action: ReduxAction<{ applicationId: string }>, action: ReduxAction<{ applicationId: string; pageId: string }>,
) { ) {
const { applicationId } = action.payload; const { applicationId, pageId } = action.payload;
yield put({ type: ReduxActionTypes.START_EVALUATION }); yield put({ type: ReduxActionTypes.START_EVALUATION });
yield all([ yield all([
put(fetchActionsForView(applicationId)), put(fetchActionsForView(applicationId)),
@ -164,10 +164,11 @@ export function* initializeAppViewerSaga(
take(ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS), take(ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS),
]); ]);
const pageId = yield select(getDefaultPageId); const defaultPageId = yield select(getDefaultPageId);
const toLoadPageId = pageId || defaultPageId;
if (pageId) { if (toLoadPageId) {
yield put(fetchPublishedPage(pageId, true)); yield put(fetchPublishedPage(toLoadPageId, true));
yield take(ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS); yield take(ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS);
yield put(setAppMode(APP_MODE.PUBLISHED)); yield put(setAppMode(APP_MODE.PUBLISHED));

View File

@ -634,7 +634,6 @@ function* setWidgetDynamicPropertySaga(
yield put(updateWidgetProperty(widgetId, propertyName, value)); yield put(updateWidgetProperty(widgetId, propertyName, value));
} else { } else {
delete dynamicProperties[propertyName]; delete dynamicProperties[propertyName];
// TODO (hetu) can we eliminate this use of validation
const { parsed } = yield call( const { parsed } = yield call(
validateProperty, validateProperty,
widget.type, widget.type,

View File

@ -13,10 +13,7 @@ import {
ReduxActionErrorTypes, ReduxActionErrorTypes,
ReduxActionTypes, ReduxActionTypes,
} from "constants/ReduxActionConstants"; } from "constants/ReduxActionConstants";
import { import { getUnevaluatedDataTree } from "selectors/dataTreeSelectors";
getDataTree,
getUnevaluatedDataTree,
} from "selectors/dataTreeSelectors";
import WidgetFactory, { WidgetTypeConfigMap } from "../utils/WidgetFactory"; import WidgetFactory, { WidgetTypeConfigMap } from "../utils/WidgetFactory";
import Worker from "worker-loader!../workers/evaluation.worker"; import Worker from "worker-loader!../workers/evaluation.worker";
import { import {
@ -147,7 +144,8 @@ export function* validateProperty(
value, value,
props, props,
}); });
return yield take(workerChannel); const response = yield take(workerChannel);
return response.data;
} }
return { isValid: true, parsed: value }; return { isValid: true, parsed: value };
} }

View File

@ -95,6 +95,15 @@ ctx.addEventListener("message", e => {
ctx.postMessage(true); ctx.postMessage(true);
break; break;
} }
case EVAL_WORKER_ACTIONS.VALIDATE_PROPERTY: {
const { widgetType, property, value, props } = rest;
const result = validateWidgetProperty(widgetType, property, value, props);
ctx.postMessage(result);
break;
}
default: {
console.error("Action not registered on worker", action);
}
} }
}); });