commit
d7e27be689
|
|
@ -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>
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
|
|
|
||||||
79
app/client/cypress/fixtures/Js_toggle_dsl.json
Normal file
79
app/client/cypress/fixtures/Js_toggle_dsl.json
Normal 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": []
|
||||||
|
}
|
||||||
43
app/client/cypress/fixtures/PageLoadDsl.json
Normal file
43
app/client/cypress/fixtures/PageLoadDsl.json
Normal 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": []
|
||||||
|
}
|
||||||
|
|
@ -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 }}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -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",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user